在SpringMVC中@RequestParam为什么可以获得文件上传的数据?
在做springmvc文件上传的时候通常都会用这种方法获得上传的文件数据
//desc,file是页面上标签的id属性
@RequestMapping(value="/testUpload",method=RequestMethod.POST)
public String testUpload(@RequestParam(value="desc",required=false) String desc, @RequestParam("file") MultipartFile multipartFile) throws IOException{
System.out.println("desc : "+desc);
System.out.println("OriginalFilename : "+multipartFile.getOriginalFilename());
InputStream inputStream = multipartFile.getInputStream();
System.out.println("inputStream.available() : "+inputStream.available());
System.out.println("inputStream : "+inputStream);
return "success";
}
但是就我所知
@RequestParam是将请求参数映射到请求处理方法的形参中
常用来处理简单类型的绑定,用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容。
可是文件上传的时候Content-Type:为multipart/form-data,那么为什么此时@RequestParam可以得到文件数据,我个人的理解是MultipartFile 的原因,可能是因为springmvc的文件上传解析器起的作用,但是我还是没理解怎么做到的
可以认为@RequestParam也可以处理multipart/form-data吗。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果看下spring的源码会发现,spring在参数处理的时候会把Content-Type解析为MediaType,然后由spring框架中注册的具体RequestBodyAdviceAdapter来处理,不同的Content-Type会对应不同的RequestBodyAdviceAdapter。这个实现类实现了对上传文件的解析。
spring mvc上传文件的时候,你需要在spring mvc配置文件中配置org.springframework.web.multipart.commons.CommonsMultipartResolver文件上传解析器。
1:当一个请求过来的时候,会调用DispatcherServlet类中的doDispatch(HttpServletRequest, HttpServletResponse)方法。
doDispatch方法体
2:在doDispatch方法体中调用checkMultipart(request)方法判断是否是文件上传的请求,判断是根据Content-type来的,如果是文件上传的请求,在checkMultipart(request)方法中就会调用在CommonsMultipartResolver中的方法进行文件解析(实际是调用apache commons-fileupload的文件长传插件),解析完成后,其实文件已经上传到服务器本地磁盘了,请看下面的代码片段。
在checkMultipart方法体中调用了CommonsMultipartResolver类的resolveMultipart方法去解析文件,该方法返回的是MultipartHttpServletRequest对象,该对象中存有已经上传的服务器本地的文件对象。
3:获取具体处理器的方法(mv = ha.handle(processedRequest, response, mappedHandler.getHandler()) 这行代码)。
如果是文件上传的话,processedRequest是上面的checkMultipart方法返回的对象。
实际调用的org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter类的handle方法,该方法中获取实际被调用的方法参数上有哪些注解,然后根据注解的一些配置,从processedRequest获取对应的值。
比如你上面的testUpload()方法。在AnnotationMethodHandlerAdapter的handle()的方法中会获取testUpload()的方法参数有@RequestParam这个注解,然后解析这个注解,从processedRequest请求中获取到desc的值,获取到名为file的文件,最后调用testUploaad()方法。具体是怎么解析的可以看看org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(Method, Object, NativeWebRequest, ExtendedModelMap)这个方法体。