개인 프로젝트를 진행하던 중에 이미지 파일 업로드를 구현하기 위해 필수적인 이미지 파일 저장 코드를 구현해보았다.
implementation 'commons-fileupload:commons-fileupload:1.4'
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
@PostMapping("/join")
public String join(@Valid @ModelAttribute BusinessCreateDto dto, MultipartFile[] files) {
dto.setUploadFile(files);
businessService.saveBusiness(dto);
return "redirect:/";
}
HTML에서 file 타입으로 선언된 input들은 dto에 포함되지 않고, MultipartFile 배열을 통해 불러온다. 이 때, MultipartFile 배열의 이름과 input의 name이 서로 같아야 Controller에서 업로드된 파일 정보를 불러올 수 있다.
public void saveBusiness(BusinessCreateDto dto, String userEmail) throws Exception {
User user = userRepository.findByEmail(userEmail);
dto.setUser(user);
Business saveBusiness = dto.toEntity();
businessRepository.save(saveBusiness);
fileService.uploadFile(dto.getUploadFile(), saveBusiness.getId());
}
public class ImageFile extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FILES_SEQ_GEN")
private Long id;
private String uploadPath;
private String uuid;
private String originalFileName;
private String fileName;
}
private static final String uploadFolder = "FILE_UPLOAD_PATH";
public void uploadFile(MultipartFile[] uploadFile, long businessId) {
File uploadPath = new File(uploadFolder, String.valueOf(businessId));
if(!uploadPath.exists()) {
uploadPath.mkdirs();
}
for(MultipartFile multipartFile : uploadFile) {
String uploadFileName = multipartFile.getOriginalFilename();
String uuid = UUID.randomUUID().toString();
uploadFileName = uuid + "_" + uploadFileName;
File saveFile = new File(uploadPath, uploadFileName);
try {
multipartFile.transferTo(saveFile);
ImageFile file = ImageFile.builder()
.originalFileName(multipartFile.getOriginalFilename())
.fileName(uploadFileName)
.uuid(uuid)
.uploadPath("/images/" + businessId + "/" + uploadFileName)
.build();
fileRepository.save(file);
} catch(Exception e) {
log.error(e.getMessage());
}
}
}
UUID는 이미지 파일의 이름을 DB에 저장할 때, 같은 이름을 가진 파일이 여러 개 존재할 수 있기 때문에, 이들을 서로 구별하기 위해 생성되는 랜덤 아이디와 비슷하다고 볼 수 있다.