IT/자바, 스프링
서블릿으로 받은 MultipartFile에 대한 NoSuchFileException
thesse
2022. 9. 19. 10:09
300x250
반응형
MultipartFile의 임시적인 속성
멀티파트파일은 임시 파일로 생성되었다가 해당 메소드가 종료되면 사라진다고 한다!
(이걸 몰라서 얼마나 삽질을 한 건지...)
때문에 @Async 메소드로 달아서 처리하거나
다른 pubic 메서드로 넘겨서 처리하려고 하면 파일을 찾지 못하는 경우가 발생하는 것.
1) async로 넘겨야 할 경우 물리적으로 복사해둔 후 메소드가 끝날때 지워주는 방식을 통해 영속적으로 사용할 수 있고
2) 같은 클래스 내에서 호출하여 파일을 가공하는 경우 private 메소드로 사용하면 된다.
기존 방식
Controller → Service → AsyncService → CloudService (여기에서 변환)
위와 같이 멀티파트파일을 넘겨 넘겨 받아서
클라우드 스토리지에 올리기 직전 MultipartFile -> File로 변환하려 했다.
그러나 CloudService에서 멀티파트파일은 메타정보만 가지고 있고
/tmp/tomcat....../work/Tomcat/localhost/ROOT 아래에 있는 .tmp 파일은
Service 클래스에서 async 메서드를 호출하고 리턴됐을 때 이미 사라지고 없는 상태인 것이다. (NoSuchFile)
해결
Controller → Service (여기에서 변환) → AsyncService → CloudService
이렇게 async 메서드를 호출할 때 애초에 변환된 File 객체를 넘겨줘서 처리하자
더 이상 익셉션이 발생하지 않고 잘 돌아갔다.
모든 처리가 끝난 뒤 생성한 파일을 삭제해주는것까지 잊지 말자!
private File convert(MultipartFile file) {
File convFile = null;
boolean result = true;
try {
// 혹시나 파일 이름이 중복될 수 있으니 파일 이름 앞에 랜덤한 숫자값을 덧붙여줌
convFile = new File(tmpLocation + "/" + Math.abs(LocalDateTime.now().hashCode()) + "_" + URLDecoder.decode(file.getOriginalFilename(), "UTF-8"));
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
return convFile;
} catch (Exception e){
result = false;
e.printStackTrace();
} finally {
if(result=false && convFile.exists()){
convFile.delete();
}
}
return null;
}
300x250
반응형