티스토리 뷰

Spring-boot/응용

[Spring-boot] AWS S3 연동

응애~ 개발자 2022. 9. 23. 18:05
728x90
반응형

안녕하세요. AWS java SDK를 추가해서 Spring-boot에 AWS 연동 해서 파일 처리 하는 방법을 포스팅 하겠습니다.

자세하게 작성할려고 했는데.. 다시  S3 버킷 만들고 파일 업로드 되는 과정을 다 작성하기에는 시간이 많이 걸리거 같아서자세한것은 나중에 올리고 필요한것만 올리겠습니다.

1. 설정하기

 먼저 spring-boot 연동 하기전에 필수적으로 작업해야 되는 부분이 있다. 파일 저장할 버킷과 접근 관련 키이다.

AWS에 S3 버킷 생성과 IAM추가해서 해서 접근 키까지 받아오는 방법은 아래의 사이트에서 참조 하면된다.

https://jih3508.tistory.com/17

 

[AWS] S3설정 하는 방법

 안녕하세요. 이번에는 S3 설정 하는 방법에 대해서 포스팅 하겠습니다. 1. 버킷은 만든다. 일단 퍼블릭 엑세스 차단을 다 풀어준다. 나중에 S3 관련 API를 사용해서 업로드 테스트시 접근 불가로

jih3508.tistory.com

 버킷 생성과 접근 키를 받아오는것까지 한 다음 Spring-boot에 설정 하면된다.

1. Maven 또는  Gladle 추가 하기

  • Maven이면 pom.xml 파일에 dependency 추가하면된다.
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-aws</artifactId>
  <version>2.2.6.RELEASE</version>
</dependency>
  • gradle
implementation 'com.amazonaws:aws-java-sdk-s3'

2. application.yalm 설정

cloud:
  aws:
    credentials:
      accessKey: ${엑세스키}
      secretKey: ${비밀엑세스키}
    s3:
      bucket: ${버킷명 또는 버킷명/저장할 경로}
    region:
      static: ap-northeast-2
    stack:
      auto: false

3. Config설정

Config.java

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

@Configuration
public class Config {


    @Value("${cloud.aws.credentials.access-key}")
    private String accessKey;
    @Value("${cloud.aws.credentials.secret-key}")
    private String secretKey;
    @Value("${cloud.aws.region.static}")
    private String region;

    @Bean
    public AmazonS3Client amazonS3Client() {
        BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
        return (AmazonS3Client) AmazonS3ClientBuilder.standard().withRegion(region).withCredentials(new AWSStaticCredentialsProvider(awsCreds)).build();
    }
}

이러면 기본적인 환경세팅은 끝난것이다.

 

2. 코드 작성

 환경 세팅이 끝나으면 그 다음 부터는 예제 코드이다.

1. S3 Util 기본 세팅

@Component
@RequiredArgsConstructor
@Slf4j
public class S3Util {

	private final AmazonS3Client amazonS3Client;
	@Value("${cloud.aws.s3.bucket}")
	private String bucket; // 버킷주소
	@Value("${cloud.aws.s3.url}")
	private String s3Url; // 버킷주소

	// 버킷 주소 출력
	public String getBucketName(){
		return bucket;
	}

	@Value("${cloud.aws.credentials.access-key}")
	private String accessKey;
	@Value("${cloud.aws.credentials.secret-key}")
	private String secretKey;
}

 S3에 처리하는 작업을 위해서 S3Util 파일 생성한다. 그 다음 S3 접근을 위해서 application.yalm 파일에 작성한 키, uri, 경로 값들을 가져온다.

 

2. S3 단건 파일 업로드

  • controller
	
    @Autowired
    S3Util s3Util;
    
    @PostMapping(value = "S3SingleUpload")
    public JsonObject S3SingleUpload(@RequestParam Map<String, Object> param , @RequestParam(value = "D_IMG_FILE", required = false) MultipartFile multipartFile){
        // s3 업로드(Sample Code 예제로 인해서 Controll 단에서 데이터 처리 하는데.. 실제로는 Service 단에서 처리 해야 한다.)
        String url = s3Util.updateFile(multipartFile);
        log.info("S3 Upload Result URL: " + url);
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("uploadUrl", url);
        return jsonObject;
    }
  •  S3Util
/**
	 * S3에 파일 업로드(MultipartFile → File)
	 * @param multipartFile
	 * @param dirName
	 * @return
	 * @throws IOException
	 */
	public String uploadFiles(MultipartFile multipartFile, String dirName) throws IOException {
		log.info(bucket);
		// MultipartFile → File로 변환 하는 작업
		File uploadFile = convert(multipartFile)  // 파일 변환할 수 없으면 에러
			.orElseThrow(() -> new IllegalArgumentException("error: MultipartFile -> File convert fail"));

		return upload(uploadFile, dirName);
	}

	/**
	 * S3에 파일 업로드(S3에 업로드 할 파일명 UUID로 설정)
	 * @param uploadFile
	 * @param filePath
	 * @return
	 */
	public String upload(File uploadFile, String filePath) {
		String fileName = filePath + "/" + UUID.randomUUID() + "_" + uploadFile.getName();   // S3에 저장할 파일아름
		log.info("fileName: " + fileName);
		String uploadImageUrl = putS3(uploadFile, fileName); // s3로 업로드
		removeNewFile(uploadFile); // 서버에 있는 파일 삭제
		return uploadImageUrl;
	}

	/**
	 * S3 서버에 파일 업로드
	 * @param uploadFile
	 * @param fileName
	 * @return
	 */
	private String putS3(File uploadFile, String fileName) {
		log.info("uploadFile:" + uploadFile.toString());
		//S3 서버에 파일 업로드
		amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile).withCannedAcl(CannedAccessControlList.PublicRead));
		return amazonS3Client.getUrl(bucket, fileName).toString();
	}

	/**
	 * 로컬에 있는 파일 삭제
	 * @param targetFile
	 */
	private void removeNewFile(File targetFile) {
		if (targetFile.delete()) {
			log.info("File delete success");
			return;
		}
		log.info("File delete fail");
	}

	/**
	 * MutipartFile → File 변환 하는 작업
	 * @param file
	 * @return
	 * @throws IOException
	 */
	private Optional<File> convert(MultipartFile file) throws IOException {
		log.info("fileDir: " + System.getProperty("user.dir") + "/" + file.getOriginalFilename() );
		File convertFile = new File(System.getProperty("user.dir") + "/" + file.getOriginalFilename());
		if (convertFile.createNewFile()) { // 바로 위에서 지정한 경로에 File이 생성됨 (경로가 잘못되었다면 생성 불가능)
			try (FileOutputStream fos = new FileOutputStream(convertFile)) { // FileOutputStream 데이터를 파일에 바이트 스트림으로 저장하기 위함
				fos.write(file.getBytes());
			}catch(Exception e) {

			}

			return Optional.of(convertFile);
		}
		return Optional.empty();
	}

3 파일 삭제

 파일 삭제하기 위해서는 S3저장되있는 주소와 위치만 알면 된다.

  • S3Util
/**
	 * S3서버에 파일 삭제
	 * @param source
	 * @param path
	 */
	public void deleteFile(String source, String path){
		amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, path + "/" + source));
	}

4. 파일 업로드

 파일 업로드를 하기 위해서는 먼저 FileUVo 객체를 만든 다음 기존 파일에 대한 데이터들을 저장한다.

  • FileUVo
@Data
@Builder
@AllArgsConstructor
@RequiredArgsConstructor
public class FileUVo {

	String fileMaskNm; // 파일 마스킹 이름
	String fileOrgnm; // 파일 원본이름
	String fileType; // 파일 확장자
	String filePath; // 파일 경로
	long fileSize; // 파일 사이즈
	String serverPath; // S3 서버 주소
}
  • S3Utile

파일 Vo객체에 기존 원래 파일관한 정보를 만든후 S3Utile에서 S3서버에 기존 파일을 삭제하고 다시 새로 만든다.  기존 파일을 변경하는 방법은 찾아 봐야 하는데 아직 찾지 못해서 찾아본후에 다시 작성하겠다. 이 방법으로 파일 변경하는 작업은 추천하지 않는다. 다만 S3가 무료이면서 무제한으로 저장이 가능하면 새로 추가 하면되지만 저장용량이나 비용측면을 고려해서 이 방법은 어떻게 보면 해볼만한 작업이라고 생각한다.

 

	public String updateFile(FileUVo fileUVo, MultipartFile multipartFile) throws IOException {
		deleteFile(fileUVo.getFilePath() + "/" + fileUVo.getFileOrgnm());
		return uploadFiles(multipartFile, fileUVo.getFilePath());
	}
728x90
반응형

'Spring-boot > 응용' 카테고리의 다른 글

[SpringBoot] Jquery로 서버에 파일 보내는 방법  (0) 2022.09.30
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함