转载:https://www.cnblogs.com/yskcoder/p/4718198.html

这两天在用spring进行上传上遇到问题,今天进行了问题的排查,这个过程也增加了我看spring源码的兴趣!还是很有收获的!

首先先给A组提供了上传接口,并没有在spring的配置文件进行multipartResolver的配置,后台Controller的java的获取为:

MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
MultipartFile file = multipartRequest.getFile("file");
String a1 = multipartRequest.getParameter("a1");

将request请求的上下文转换为MultipartResolver,然后转换为MultipartHttpServletRequest请求,通过multi请求就可以获取对应的file文件信息,这样的方法没有问题,后台能获取到相应的参数;

稍后组里另一个同事也用到上传,基于网上查的资料,认为应该把配置文件给加上去了,于是问题出来了,也造成了我记录该博客的原因:

10485760000

4096

进行该配置后,我在后台的该方法获取file为空造成了上传错误,刚开始我也纳闷,按道理spring的上传应该需要这样的配置,同事也是觉得我大意了没有进行配置好心给我进行了修改,但是反而造成了bug,线下环境测试将该配置去除功能ok。好了,做了这么多年开发,不能因为fixed bug而不进行原理的问题查看,这样的修改连自己都过不去。

搜了资料,做了测试,有了以下的总结,有问题欢迎大家拍砖!

最后上传问题的方案:

(一):
1、在spring-config配置了 之后

后台的获取有两种方法:

1、指定@RequestParam MultipartFile file 例如:public Map<String, Object> logsUpload(@RequestParam MultipartFile file,@RequestParam(value="key") String key)参数;

2、将request转化为MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)(request);

原理是:使用spring的CommosMultipartResolver 配置MultipartResolver 用于文件上传,DispatcherServlet 将调用 MultipartResolver 的 isMultipart(request) 方法检查当前 Web 请求是否为 multipart类型。如果是,DispatcherServlet 将调用 MultipartResolver 的 resolveMultipart(request) 方法,对原始 request 进行装饰,并返回一个 MultipartHttpServletRequest 供后继处理流程使用(最初的 HttpServletRequest 被偷梁换柱成了 MultipartHttpServletRequest),否则,直接返回最初的 HttpServletRequest。也就是说请求一旦被 MultipartResolver 接手,它就会解析请求中的文件,而不必等待后续 controller 主动从 MultipartRequest 中 getFile,所以在配置了MultipartResolver后,再通过这样的方法

MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);

是获取不到file的,因为控制器已经帮我们进行了转换 直接获取即可。

如果你使用该方法发觉获取没有问题,你可以看看给这个方法是不是配置了servlet,如果配置了servlet是不走这个 MultipartResolver控制,是能获取成功的。

(二)

无需进行spring-config的配置,直接在后台获取进行转换即可,也就是我最初的写法。

MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
MultipartFile file = multipartRequest.getFile("file");
String key = multipartRequest.getParameter("key");

然后项目具体需要什么样的修改,自己结合业务斟酌即可。

自己讲的不深,看了很多文章资料,也是这篇给的启迪最大:

http://exceptioneye.iteye.com/blog/1314958

spring的multipartResolver和java后端获取的MultipartHttpServletRequest方法对比 (附:遇到的坑)的更多相关文章

  1. spring的multipartResolver和java后端获取的MultipartHttpServletRequest方法对比

    这两天在用spring进行上传上遇到问题,今天进行了问题的排查,这个过程也增加了我看spring源码的兴趣!还是很有收获的! 首先先给A组提供了上传接口,并没有在spring的配置文件进行multip ...

  2. Spring core resourc层结构体系及JDK与Spring对classpath中资源的获取方式及结果对比

    1. Spring core resourc层结构体系 1.1. Resource相关结构体系 1.2. ResourceLoader相关体系 2. JDK与Spring对classpath中资源的获 ...

  3. java中获取接口(方法)中的参数名字(eclipse设置编译参数)(java8 javac -parameters)

    interface接口参数 jdk1.7及以前使用spring功能实现的: 注意: 1.该功能只能获取类的方法的参数名,不能获取接口的方法的参数名. public static void test() ...

  4. Java中获取路径的方法_自我分析

    就目前的我来说最常用的两种获取路径的方法是  class.getRecource(filename) 和 class.getclassloader.getRecource(filename) 这两者的 ...

  5. Java 后端微信小程序支付demo (网上说的坑里面基本上都有)

    Java 后端微信小程序支付 一.遇到的问题 1. 商户号该产品权限未开通,请前往商户平台>产品中心检查后重试 2.签名错误 3.已经调起微信统一下单接口,可以拿到预支付ID,但是前端支付的时候 ...

  6. java中获取路径的方法

    在class获取路径的方法,getResource有没有“\”的区别 System.out.println("" + this.getClass().getResource(&qu ...

  7. JSSDK实现微信自定义分享---java 后端获取签名信息

    一.首先说下关于微信Access_token的问题,微信Access_token分为2中: 1.授权token获取方式: 这种token需要code值(如何获取code值查看官方文档) "h ...

  8. java中获取ServletContext常见方法

    http://blog.sina.com.cn/s/blog_3fe961ae0100wjnf.html 1.在javax.servlet.Filter中直接获取 ServletContext con ...

  9. java 反射获取属性值 方法

    public static void main(String[] args) throws SecurityException, ClassNotFoundException, IllegalArgu ...

随机推荐

  1. ActiveMQ producer同步/异步发送消息

    http://activemq.apache.org/async-sends.html producer发送消息有同步和异步两种模式,可以通过代码配置: ((ActiveMQConnection)co ...

  2. VSS迁移详细教程

    本文默认迁移机和目标机已是安装好VSS服务,如果没装好参见VSS+SourceAnywhere for VSS搭建版本控制系统教程 如果你只想以最快的速度迁移库而并不关心VSS的一些操作使用,那么可直 ...

  3. redis事件监听及在订单系统中的使用

    https://blog.csdn.net/qq_37334135/article/details/77717248 通常在网上买好物品,或者说手机扫码后,点击付款,这时就会向后台发送请求,生成订单信 ...

  4. SpringBoot的Profile文件

    1.多Profile文件我们在主配置文件编写的时候,文件名可以是application-{profile}.properties/yml默认使用application.properties的配置 2. ...

  5. linux 程序实现后台运行

    先上代码: getopt函数获取参数  -d 控制台控制运行  -D 后天运行  -h 调用show_help函数. 编译命令 gcc -g -W test.c -o test 注意后台运行 ./te ...

  6. 运行网站项目时,有时出现Bad Request,该怎么解决?

    有时运行网站项目时,出现Bad Request问题

  7. jquery自定义类的封装

    如何用jquery自定义一个类?(demo参考) /*简单使用*/ (function($){ //el操纵对象,option属性值 $.love = function(el,option){ var ...

  8. PAT-GPLT训练集 L1-043 阅览室

    PAT-GPLT训练集 L1-043 阅览室 注意:连续的S和E才算一次借还 代码: #include<iostream> #include<cstdio> using nam ...

  9. delphi 演示数据路径

    链接里默认的--------------------------- Error --------------------------- I/O error for file "C:\Prog ...

  10. 上传本地代码到GitHub上

    由于经常忘记Git的相关代码,百度多了自然不耐烦,干脆自己写个简单的博客记录一下代码及流程了...... 1.在GitHub上新建一个仓库: 2.创建完后在仓库左上角的ssh上copy一下地址: 3. ...