Spring
[Spring Boot] S3 이미지 업로드
JangJangYi
2021. 6. 2. 11:35
Spring Boot로 S3에 이미지 업로드 하기 Ver.1
의존성을 먼저 추가해주어야 합니다
// AWS S3
compile group: 'org.springframework.cloud', name: 'spring-cloud-aws', version: '2.2.1.RELEASE', ext: 'pom'
// https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3
implementation group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.993'
MultipartFile로 이미지 파일을 주고 받기
- 총 3가지의 방법이 있습니다.
- @RequestParam MultipartFile 타입 사용
- ServletRequest or MultipartHttpServletRequest 타입 사용
- 사용자 정의 Class 사용
저는 여기서 첫 번째 방법인 @RequestParam 을 사용하겠습니다.
- 이유는 Controller의 요청 파라미터 타입 중 MultipartFile 타입에 해당하는 한 가지를 직접 골라서, File 데이터를 직접 다룰 수 있습니다.
들어가기전에 유의할 점!
Controller.java
@PostMapping("/api/boards")
public Boards createBoards(HttpServletRequest req,
@RequestParam(value = "files", required = false) List<MultipartFile> files,
@RequestParam("title") String title,
@RequestParam("contents") String contents,
@RequestParam("price") String price)
...
}
- 인자를 보시면 @RequestParam(value = "files", required = false) List
files 로 되어 있습니다. 여기서 프론트에서 파일 이름은 files로 보내야 한다는 점과 사용자가 이미지 파일을 안보낼 수 도 있기 때문에 required = false로 지정하였습니다. 또한 여기서 주의 할 점은 required = false 이런식으로 해놓으면 NULL값이 들어오기 때문에 NULL 값 처리를 해주어야 합니다. - 그리고 현재 저의 프로젝트에서는 List로 Multipart를 받고 있지만 이거는 단일로 받던지 다중으로 받던지 선택입니다!
S3Service.java
@Value("AKIASMHMW5M2RB6R6NFB")
private String accessKey;
@Value("rmXhmQbSZUoNDs+e4RbkBiLdws4PFTErfPs9I7/k")
private String secretKey;
@Value("clonedanggeon")
private String bucket;
@Value("ap-northeast-2")
private String region;
- 현재는 Access Key와 Secret Key의 값을 직접 넣어주고 있는데 원래는 .yml or .properties에 데이터를 넣어서 받아와야한다! 이 부분은 다음편에 설명하겠습니다 :)
- @Value로 S3Service 빈을 생성할 때 , 설정 파일의 S3 관련 프로퍼티 값을 매핑한다.
@PostConstruct
public void setS3Client() {
AWSCredentials credentials = new BasicAWSCredentials(this.accessKey, this.secretKey);
s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(this.region)
.build();
}
- @PostContruct로, S3Service가 사용되기 이전에 AmazonS3Client 객체를 생성한다.
public String upload(MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename().replace(" ","");
Date date_now = new Date(System.currentTimeMillis()); // 현재시간을 가져와 Date형으로 저장한다
SimpleDateFormat fourteen_format = new SimpleDateFormat("yyyyMMddHHmmss");
System.out.println(fourteen_format.format(date_now)); // 14자리 포멧으로 출력한다
fileName = fourteen_format.format(date_now) + fileName;
System.out.println(fileName);
s3Client.putObject(new PutObjectRequest(bucket, fileName, file.getInputStream(), null)
.withCannedAcl(CannedAccessControlList.PublicRead));
return s3Client.getUrl(bucket, fileName).toString();
}
- 간혹가다 파일명이 특수문자와 한글로 파일명이 된게 있기 때문에 파일명을 시간포맷으로 바꿔준다. 업로드는 S3에서 메서드를 따로 제공해주는데 코드에서 보면 putObject를 사용하면 된다
- 업로드 시에는 파일 명과 경로는 직접 지정하는 경우와 그렇지 않은 경우를 나눠 오버로딩하고, 삭제 시에는 파일이 존재하는지 확인하기 위해서 AmazonS3Client의 doesObjectExist 메소드를 사용했다. 존재하는 파일인 경우에만 경로의 파일을 삭제한다.