클라이언트가 이미지를 업로드하면 서버는 프로젝트 외부에 있는 폴더에 사진을 저장하고 DB 에는 사진의 경로와 사진이름으로 조합된 문자열을 DB 에 저장한다 !
MultipartFile
를 이용한다.@Data
public class ImageUploadDto {
private MultipartFile file;
private String caption;
}
@AuthenticationPrincipal
를 사용해서 갖고온다.PrincipalDetails
은 SpringSecurity
의 UserDetails 인터페이스
를 구체화 한 클래스이다.@PostMapping("/image")
public String imageUpload(@ModelAttribute ImageUploadDto imageUploadDto,
@AuthenticationPrincipal PrincipalDetails principalDetails) {
imageService.사진업로드(imageUploadDto,principalDetails);
return "redirect:/user/"+principalDetails.getUser().getId();
}
실제 이미지 업로드가 구현되는 로직이다.
application.yml
에서 설정이 필요하다.spring.servlet.multipart.enabled
옵션을 true
로 설정해준다.file.path
에는 프로젝트 외부에 upload 파일의 경로를 적어준다.
spring:
# 생략 ...
servlet:
multipart:
enabled: true
max-file-size: 2MB
# 생략 ...
file:
path: /Users/jaeyoung/Desktop/workspaces/upload/
uploadFolder
변수는 application.yml
파일에 지정했던 file.path
의 경로를 가져와서 저장하는 변수다.@Value
어노테이션은 lombok 이 아닌 spring 에서 제공하는 어노테이션이다.UUID
를 사용하는 이유는 사용자는 똑같은 이미지 파일을 업로드할 수 있다. 계속하게 되면 서버에서는 똑같은 사진을 구별할 필요가 있다. UUID 의 고유 식별자를 이용하여 서버에서 똑같은 사진을 구분하기 위해 사용한다.getOriginalFilename()
메서드를 이용하면 된다.Files.write()
메서드를 실행한다.@RequiredArgsConstructor
@Service
public class ImageService {
private final ImageRepository imageRepository;
@Value("${file.path}")
private String uploadFolder;
@Transactional
public void 사진업로드(ImageUploadDto imageUploadDto, PrincipalDetails principalDetails){
UUID uuid = UUID.randomUUID();
String imageFileName = uuid + "_" + imageUploadDto.getFile().getOriginalFilename();
Path imageFilePath = Paths.get(uploadFolder + imageFileName);
try{
Files.write( imageFilePath,imageUploadDto.getFile().getBytes());
} catch (Exception e){
e.printStackTrace();
}
Image imageEntity = imageRepository.save(imageUploadDto.toEntity(imageFileName,principalDetails.getUser()));
}
}
💡 중요포인트!!
1. application.yml 설정파일을 수정해서 multipart 옵션을 활성화하고, 이미지저장되는 경로설정
2. UUID 와 이미지파일 이름을 이용하여 고유한 식별자 생성해서 DB 에 저장
3. 실제 이미지를 저장하는 Files.write() 에서는 이미지를 Byte 로 변환하는것!