uploadImageUrl을 String으로 단순히 반환하던 이 코드를, ServerFileService의 구조와 맞추기 위해 리팩토링을 진행해보기로 했다.
private Optional<File> convert(MultipartFile multipartFile) throws IOException{
// 디렉토리 경로 수정하기
File convertFile = new java.io.File(System.getProperty("user.dir") + "/" + multipartFile.getOriginalFilename());
if(convertFile.createNewFile()){
try (FileOutputStream fos = new FileOutputStream(convertFile)) {
fos.write(multipartFile.getBytes());
}
return Optional.of(convertFile);
}
return Optional.empty();
}
convert 함수에서 주어진 multipartFile에 대해 ServerFileService와는 다른 로직으로 File 객체로 만들어서 반환하고 있다.
그리고 이 반환체를 S3upload함수의 매개변수에 넣어 사용하고 있는데,
private String S3upload(File uploadFile){
String fileName = getFolder() + "/" + UUID.randomUUID() +uploadFile.getName();
String uploadImageUrl = putS3(uploadFile, fileName);
removeNewFile(uploadFile);
return uploadImageUrl;
}
이 함수 내에서 getFolder() 호출, UUID 생성, getOriginalName()을 통해 fileName을 만들고, putS3함수를 호출해 uploadImageUrl을 만들고 있었다.
여기서 removeNewFile을 수행해야하는 이유 찾기
여기서 반환되는 uploadImageUrl은 ServerFileService의 File.getAbsolutePath()와 동일함을 알 수 있다.
기존에 convert 함수에서 user.dir 속성을 가져와 만든 convertFile이 곧 uploadImageUrl이 되는 것이다.
private String putS3(File uploadFile, String fileName){
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile)
.withCannedAcl(CannedAccessControlList.PublicRead));
return amazonS3Client.getUrl(bucket,fileName).toString();
}
String으로 반환할 필요가 없으니 getUrl을 할 필요도 없으며, 저장 로직만 사용하면 된다.
또한 S3upload함수에서도, fileName 변수에 getFolder()와 UUID(), 그리고 getOriginalName()을 한번에 다 때려 넣는게 아니라 하나하나 변수화해서 attachFileDto에 set해야 하므로 모두 하나의 함수에서 처리한다.
그렇게 완성된 upload 함수는 다음과 같다.
public List<AttachFileDto> upload(MultipartFile[] uploadFile) {
List<AttachFileDto> fileDtoList = new ArrayList<>();
for (MultipartFile multipartFile : uploadFile) {
AttachFileDto attachFileDto = new AttachFileDto();
String uploadFolder = "C:\\upload";
String uploadFolderPath = getFolder();
String uploadFileName = multipartFile.getOriginalFilename();
File uploadPath = new File(uploadFolder, uploadFolderPath);
UUID uuid = UUID.randomUUID();
String fileName = uploadFolderPath + "/" + uuid + "_" + multipartFile.getOriginalFilename();
try {
File saveFile = convert(multipartFile)
.orElseThrow(() -> new IllegalArgumentException("Fail to convert MultipartFile to File"));
multipartFile.transferTo(saveFile);
// Upload file to S3 bucket
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, saveFile)
.withCannedAcl(CannedAccessControlList.PublicRead));
attachFileDto.setUuid(uuid.toString());
attachFileDto.setUploadPath(uploadFolderPath);
if (checkImageType(saveFile)) {
attachFileDto.setImage(true);
FileOutputStream thumbnail = new FileOutputStream(new File(uploadPath, "s_" + uploadFileName));
Thumbnailator.createThumbnail(multipartFile.getInputStream(), thumbnail, 100, 100);
thumbnail.close();
}
removeNewFile(saveFile);
fileDtoList.add(attachFileDto);
} catch (Exception e) {
e.printStackTrace();
}
}
return fileDtoList;
}
한 가지 차이점은 Server에 저장하는 경우 파일을 삭제하지 않았지만, S3에 저장하는 경우 서버에 저장된 파일을 삭제해 S3에만 업로드되도록 처리하는 것이다.
이렇게 S3 파일 업로드 코드 작성을 완료하였다.
'Framework > Spring' 카테고리의 다른 글
[IBAS] 첨부파일 업로드(FileService, FileController) WebMvcTest (0) | 2022.03.26 |
---|---|
Spring File Upload 구현 과정 / Controller에서 파일 데이터 받아오기 (0) | 2022.03.21 |
[IBAS] Spring MVC의 Front Controller Pattern 구현하기 (0) | 2022.03.14 |
Spring 첨부파일 다운로드 구현하기 (0) | 2022.03.05 |
Spring 첨부파일 업로드 구현하기 (0) | 2022.03.03 |