Spring MVC 3.1以后版本 MultipartFile的一个问题
使用Spring web MVC的时候,请求参数到方法参数的绑定是个很好用的特性。
下面是一个你可能会遇到的问题:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResultView upload(@RequestParam(value = "file", required = false) MultipartFile file)
于是你会认为,参数file的required属性已经是false,提交multipart请求或者提交form-data请求都可以。 事实不是这样的,在spring 3.1以后,如果请求是普通post,即使参数被标记了required=false,也会出错。 这是一个普通post请求的异常堆栈
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.assertIsMultipartRequest(RequestParamMethodArgumentResolver.java:185)
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.resolveName(RequestParamMethodArgumentResolver.java:150)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:86)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
使用Spring web MVC的时候,请求参数到方法参数的绑定是个很好用的特性。
下面是一个你可能会遇到的问题:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResultView upload(@RequestParam(value = "file", required = false) MultipartFile file)
于是你会认为,参数file的required属性已经是false,提交multipart请求或者提交form-data请求都可以。 事实不是这样的,在spring 3.1以后,如果请求是普通post,即使参数被标记了required=false,也会出错。 这是一个普通post请求的异常堆栈
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.assertIsMultipartRequest(RequestParamMethodArgumentResolver.java:185)
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.resolveName(RequestParamMethodArgumentResolver.java:150)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:86)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
... 后面堆栈信息省略
Spring在处理请求映射的时候,如果发现某个请求参数是MultipartFile类型的,会判断请求是否是MultipartHttpServletRequest,如果请求不是这个类型,即使参数不是必须的(required=false),也会抛出异常。
【解决:】在<form>表单提交处添加 enctype="multipart/form-data"
<form name="userForm1" action="/springMVC7/file/upload" enctype="multipart/form-data" method="post"> …… </form>