이번엔 Spring에서 이미지 파일을 byte[] 변환하여 Porstgres에 bytea 타입으로 데이터를 삽입하는 방법에 대해 설명해보자.
ImageFile.java :: Entity
postgres에 설계한 DB tbl 내용을 반영한 Entity 작성
@Entity
@Table(name = "image_file")
@EntityListeners(AuditingEntityListener.class)
@Setter
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ImageFile extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "file")
private byte[] file;
}
ImageFileDto.java :: DTO
객체를 주고받을 DTO 작성
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class ImageFileDto {
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private MultipartFile file;
}
ImageFileController.java
@Tag(name = "file")
@PostMapping(value = "/file", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<Integer> registerImageFile(@ModelAttribute ImageFileDto dto) throws IOException {
imageFileService.registerImageFile(dto);
return ResponseEntity.ok().body(1);
}
기본 제공되는 DATA
public static final String MULTIPART_FORM_DATA_VALUE = "multipart/form-data";
ImageFileService.java
@Transactional(rollbackFor = Exception.class)
public void registerImageFile(ImageFileDto dto) throws IOException {
MultipartFile multipartFile = dto.getFile();
ImageFile imageFile = ImageFile.builder()
.file(multipartFile.getBytes())
.build();
imageFileRepository.save(imageFile);
}
ModelAttribute로 전달받은 Dto 객체 중 File 값을 MultipartFile로 받아주고, 해당 값의 Bytes 값을 ImageFile.java(Entity)에 Build 해준다.
Repository에 Save하면 DB에 정상적으로 저장되는 것을 확인할 수 있다.
Save는 Java에서 제공되는 메소드
ImageFileController.java
@Tag(name = "file")
@GetMapping(value = "/file/{fileId}/image", produces = {MediaType.IMAGE_JPEG_VALUE})
public ResponseEntity<byte[]> getImageFileList(@NotNull @PathVariable Long fileId) {
return ResponseEntity.ok().body(imageFileService.getImageFileList(fileId));
}
ImageFileService.java
@Transactional(readOnly = true)
public byte[] getImageFileList(Long fileId) {
ImageFile imageFile = ImageFileRepository.findByFile(fileId);
return imageFile.getFile();
}
DB에서 조회된 ImageFile 객체의 file 값 byte Array 로 반환
ImageFileRepository.java
public interface ImageFileRepository extends JpaRepository<ImageFile, Long> {
@Query(value = "select n from ImageFile n where n.id =:fileId")
ImageFile findByFile(Long fileId);
}
ImageFile 테이블에서 id 값을 조회하여 ImageFile 객체를 반환
이렇게 코드로 정리하고나니 별거 아닌 것처럼 보이는데 파일 업로드 및 변환, 반환이 정상적으로 되지 않아 여러방면으로 삽질한 결과이다.
아래 이미지는 swagger에서 동작했을 때 모습으로 정상 동작하는 것을 확인할 수 있다.