기존 JSP에서도 파일 업로드 처리를 할 수 있었지만, Spring에는 좀 더 쉽게 파일을 업로드할 수 있는 기능을 지원한다.
스프링은 multipart 처리를 위한 서포트를 지원한다.
디폴트로는 지원이 꺼진 상태로 되어있으며, 전자정부프레임워크에서는 디폴트가 켜져 있는 상태다. 물론 스프링에서도 HttpServletRequest를 인자로 하는 컨트롤러를 만들어서 MultipartRequest 객체로 처리하는 기존의 방식이 가능하지만, spring에서는 multipartResolve를 통해 더 간단하게 파일처리를 할수 있다.
CommonsMultipartResolver를 사용하기 위해서는 Apache Commons FileUpload 라이브러리를 메이븐에 추가하여야 한다.
<!--https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
IOC컨테이너에 id를 반드시 multipartResolver로 하는 아래 두 객체 중 하나를 등록한다.
(스프링에서 해당 아이디를 인식하기 때문에 id는 반드시 multipartResolver로 해야한다)
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="uploadTempDir" value="/temp"></property> // 임시디렉터리
</bean>
컨트롤러에서 파일객체를 불러올 때 별다른 처리 없이 메서드의 인자로 @RequestParam 타입을 MultipartFile객체로 받아오기만 하면 된다. (단, 마찬가지로 input name과 일치해야 함)
ex)
multiple은 하나의 인풋파일에 여러개의 파일을 선택할 수 있는 옵션이다.
추가하게 되면 같은 인풋네임으로 여러개의 파일이 넘어온다.
또는 같은 인풋네임의 여러 인풋태그가 넘어올 때도 같은방식으로 넘어온다.
※주의 : 파일이 없을 때도 객체에 담겨오기 때문에 하나의 파일을 전송할 경우 isEmpty()로 파일이 넘어왔는지 확인 후 작업을 해야한다.
받아온 객체를 업로드 처리하지 않으면 임시파일에 저장된 파일이 자동적으로 삭제되기 때문에 MultipartFile객체의 transferTo(File f) 메서드를 이용해서 업로드처리를 해야 한다.
1) 리네임과 동시에 파일객체 생성
파일객체는 실제 경로로 지정해야 하기 때문에 application객체를 뽑아서 realPath로 디렉토리를 설정하고, 두 번째 인자로 파일의 리네임을 정한다.
단, 해당 디렉터리 경로가 없을 경우 자동적으로 생성하지 않기 때문에 없으면 mkdir()로 디렉터리부터 생성해야 한다.
File file =
new File(request.getServletContext().getRealPath("/temp"), “random”);
2) transferTo() 업로드
위에서 만든 파일객체의 경로와 리네임으로 실제 업로드 하기위해transferTo()메서드로 업로드처리를 한다. MultipartFile객체.transferTo(file)
// @RequestParam MultipartFile f 일 때
File file = new File(request.getServletContext().getRealPath("/temp"), "test.png");
f.transferTo(file);
이클립스에서 실행하는 서버와 실제 서버는 다르다
이클립스에서 실행하는 서버는 테스트 서버이기 때문에 실제 파일이 저장될 경로도 달라지게 된다.
실제 파일을 서버에 저장시키기 위해서는 프로젝트를 war파일로 만들어 서버의 webapp디렉터리에 넣어야 한다. WAR파일 만들기 참고
enctype주의
기존 MultipartRequest처리 방식처럼 모든 파일처리는 post방식에 enctype이 multipart/form-data이어야 한다. MultipartRequest처리참고
일부 tomcat버전 context.xml파일 수정 필요
일부 톰캣 버전에서는 별도의 설정이 필요하다. 에러가 발생할 경우 (톰캣)apache-tomcat-8.5.45\conf\context.xml파일을 수정해야한다.
태그와 태그의 옵션을 추가해준다.
<Context allowCasualMultipartParsing="true" path="/">
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!-- <Manager pathname="" /> -->
<Resources cachingAllowed="true" cacheMaxSize="100000" />
</Context>
[출처]https://gunbin91.github.io/spring/2019/09/24/spring_12_multipart.html