Spring
Spring 파일업로드
pooney
2020. 2. 20. 16:34
파일 업로드 시 두가지 방법이 존재한다
1. form태그를 이용한 방법
<form>
<input type="file" name="file">
<button>업로드</button>
</form>
2. ajax를 이용한 방법 (formData를 이용하여 파일을 전송하는방법 formData는 가상의 form이라고 생각)
var data = event.originalEvent.dataTransfer.files;
var formData = new FormData();
formData.append("profileImg",data[0]);
$.ajax({
url:"${path}/upload/insertProfileImg",
processData : false,
contentType : false,
type:"POST",
data:formData,
dataType:"text",
success:function(result){
console.log("성공");
},
error:function(result){
console.log("실패");
}
})
서버쪽에서는 파일업로드를 위한 몇가지 설정이 필요하다. pom.xml과 web.xml , servlet.xml에 몇가지 설정을 추가해야한다
처음 servlet버전이 sprimg-mvc 프로젝트로 생성시 2.5버전이다 3.1로 버전을 변경 및 추가 하여 spring 업로드 사용가능하게 변경해아한다 이후 servlet.xml에서 multipartResolver를 빈으로 등록한다 다음 web.xml에 업로드 설정관련 사항을 추가한다
pom.xml ( 2.5 -> 3.1 변경)
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
servlet.xml
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</beans:bean>
web.xml(2.5->3.1변경)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!--파일업로드 시 servlet.xml에 multipartResolver bean으로 등록 하고 web.xml, pom.xml의 서블릿 버전 3.1로 업글 하고 web.xml에 아래와 같은 multipart-config설정 하기-->
<multipart-config>
<location>C:\\upload</location>
<max-file-size>20971520</max-file-size> <!--1MB * 20 -->
<max-request-size>41943040</max-request-size><!-- 40MB -->
<file-size-threshold>20971520</file-size-threshold> <!-- 20MB -->
</multipart-config>
</servlet>
servlet.xml과 pom.xml 설정까지하고 web.xml 같은 설정을 안하면 아래와 같은 에러가 발생한다
2월 20, 2020 4:08:11 오후 org.apache.catalina.core.StandardWrapperValve invoke
심각: 경로 [/scheduler]의 컨텍스트 내의 서블릿 [appServlet]을(를) 위한 Servlet.service() 호출이, 근본 원인(root cause)과 함께, 예외 [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.lang.IllegalStateException: 어떤 multi-part 설정도 제공되지 않았기 때문에, part들을 처리할 수 없습니다.]을(를) 발생시켰습니다.
java.lang.IllegalStateException: 어떤 multi-part 설정도 제공되지 않았기 때문에, part들을 처리할 수 없습니다.
at org.apache.catalina.connector.Request.parseParts(Request.java:2801)
at org.apache.catalina.connector.Request.getParts(Request.java:2769)
at org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1098)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:94)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:87)
at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:87)
at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1175)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1010)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
Controller
public String insertProfileImg(MultipartFile [] profileImg) {
System.out.println(profileImg[0].getOriginalFilename());
String rootUplaodPath = "C:\\upload";
String uploadPath = getFolder();
File realUploadPath = new File(rootUplaodPath, uploadPath);
if(!realUploadPath.exists()) {
realUploadPath.mkdirs();
}
return "성공";
추가적으로 파일업로드는 여러가지 라이브러리르 사용하여 가능한데 대표적으로 commons-fileupload를 많이 사용
사용방법은 아래와 같이 사용
pom.xml
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
servlet.xml
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="10485760"/><!-- 업로드최대용량 -->
</beans:bean>