https://girokeulhaja.tistory.com/55
CompletableFuture 비동기 처리로 응답 속도 향상 시키기
기존 코드 Controller@PostMappingpublic ResponseEntity uploadImage(@RequestParam("file") MultipartFile file) { try { // 1. DB에 파일 메타데이터 저장 및 응답 ImageResponse imageResponse = uploadService.saveImageMetadata(file); // 2. 비동
girokeulhaja.tistory.com
위 코드를 제대로 테스트 안 하고 응답 속도 개선만 확인했더니 대참사가 일어났다 ㅎㅎ
baboㅠ
바로 NoSuchFileException 에러가 계속 뜨는 거..
간헐적으로 나는 에러인줄 알았는데
InputStream은 한 번 읽으면 그 상태가 변경되어 더 이상 사용할 수 없게 되어 생기는 오류인듯,,
1. 이미지 크기 확일할 때 한 번
BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
2. minio에 저장할 때 한 번
.stream(file.getInputStream(), file.getSize(), -1)
보통 2번 코드에서 오류가 잡히길래 뭔가했더니,,
파일을 두번째 읽을 때는 MultipartFile의 InputStream이 이미 소비되어 문제가 발생한다고 한다.
file.getInputStream() 또는 file.getBytes()를 호출하면, MultipartFile의 내용을 읽게 된다.
이 시점에서 InputStream이 소비되므로 이후에 다시 file을 읽으려고 하면 NoSuchFileException이 발생한다.
public CompletableFuture<String> saveImageMetadata(MultipartFile file) {
return CompletableFuture.supplyAsync(() -> {
try {
// 파일 데이터를 메모리에 저장
byte[] fileBytes = file.getBytes();
// 파일 데이터를 기반으로 InputStream 생성
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(fileBytes);
// 업로드 파일명을 불러옴
String originalName = file.getOriginalFilename();
// 파일 이름이 존재하지 않는 경우
if (originalName == null) throw new IllegalArgumentException("잘못된 파일입니다.");
// 파일 정보 분리
String[] fileInfos = FileUtil.splitFileName(originalName);
// 확장자 체크
ImageExtension extension = ImageExtension.findByKey(fileInfos[1])
.orElseThrow(() -> new Exception("지원하지 않는 확장자 입니다."));
// 이미지 크기 확인
BufferedImage bufferedImage = ImageIO.read(byteArrayInputStream);
int imageWidth = bufferedImage.getWidth();
int imageHeight = bufferedImage.getHeight();
ImageRequest imageRequest = ImageRequest.create(
originalName,
extension.getKey(),
cdnBaseUrl,
imageWidth,
imageHeight
);
// 메타데이터 저장
ImageResponse imageResponse = dataService.uploadImage(imageRequest);
// 새롭게 InputStream을 생성하여 minio에 이미지 업로드
uploadImage(new ByteArrayInputStream(fileBytes), file.getContentType(), imageResponse);
return imageResponse.getOriginalFileUUID().toString();
} catch (Exception e) {
log.error("이미지 메타데이터 저장 중 오류 발생: ", e);
throw new RuntimeException(e);
}
});
}