기존에는 input type=file 태그에서 파일을 선택해서 controller단에서 Multipart[]로 받으면 그 파일 정보가 어디에 저장이 되는 지 몰랐고, 그저 요청했으니 계속 그 정보가 남아있을 것?이라는 막연한 생각만 했었다.
결론은 "아니다".
스프링 부트에서 선택해서 넘어온 파일 객체는
내장 톰캣의
C:\Users\내아이디\AppData\Local\Temp\tomcat.8091.11259971382673875650\work\Tomcat\localhost\ROOT
경로에 임시 저장되어 메모리가 올라간다.
어떻게 알게 되었을까?
회사의 기존 메서드는 아마존의 aws s3에 파일을 업로드하는 메서드 uploadA()와 파일 객체 정보를 컴퓨터 안 특정 경로로 이동했다가 그 path에서 가져와 파일 객체를 이메일 전송하는 uploadB()가 있다.
내 코드는 아래와 같았고 결과적으로 uploadA()에서 위에서 말한 톰캣 폴더 경로에서 파일 정보를 못 찾았다는 nofileException?이 발생했다.
uploadA(attach);
... 중략 ...
uploadB(attach);
uploadA()는 파일 정보를 컴퓨터 내 특정 폴더로 이동시키기 위해서 file.transferTo() 메서드를 사용했다.
결과적으로 톰캣 temp 폴더에 있던 file 객체가 통으로 transferTo()에서 정한 폴더 경로로 이동해 버린 것이다.
이제 톰캣 temp 폴더에는 해당 파일 정보가 없다.
그런데 이후에 uploadB()에서 파일을 aws에 올리기 위해서 attach 파일 정보가 필요해서 다시 톰캣 temp 폴더에 접근을 했는데? 정보가 없어서 업로드가 안되고 에러가 발생한 것이다.
새로 알게 된 점
1. file.transferTo()를 쓰면 톰캣 ~temp 폴더 안의 파일 객체가 사라진다.
2. controller에서 파라미터로 받은 파일 객체는 톰캣의 ~temp 폴더 안에 쌓인다. (;;)
여담
file_list를 담을 때 에러가 나도 핸들링을 하려면
map을 사용해서 성공하면 ("file_list", list)를 담고
실패 시 ("error", e)를 담아서
map에서 얻은 map.get("file_list")의 size()를 체크해서 유효한 경우에만 실행하게 하면 에러 발생해도 처리가 된다.