在了解Spring 文件上传执行流程之前,我们必须知道两点:

1.Spring 文件上传是基于common-fileUpload 组件的,所以,文件上传必须引入此包
2.Spring 文件上传需要在XML中配置文件上传解析器,不然程序无法执行判别

带领着这几个问题去分析Spring 文件上传:

1.文件上传解析器什么时候被初始化,在哪里被DispatcherServlet 引用
2.如何判别我们的请求上传文件的请求
3.传统的fileUpload与Spring被包装后的文件上传比较

问题抛出: 1.文件上传解析器什么时候被初始化调用的,在哪里被DispatcherServlet 引用:

  在我们在XML 中配置了如下:这个时候,MultipartResolver 最终会在Spring 实例化be an 的时候初始化,初始化的步骤会在第三个问题中一起看

<!-- 上传拦截,如最大上传值及最小上传值 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
<property name="maxUploadSize">
<value>524288000</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
<property name="defaultEncoding">
<value>utf-8</value>
</property>
</bean>

  在DispatcherServlet 中如何被引用的呢?

  聪明的你知道servlet 生命周期 init() 方法,只会被执行一次,所有的初始化动作在这里完成(org.springframework.web.servlet.DispatcherServlet),最终会调用如下的方法:  

  哈哈,这就是Spring 九大组件,没一个init..()方法就是一个组件,其中第一个就是初始化MultipartResolver

  所以我们XML 配置的id 可不是瞎取的  

  第一个问题结束;

  问题抛出:2.如何判别我们的请求是Multipart 文件上传请求:

  在doDispatch 方法中有检测我们请求的方法:如下:

   我们点进去:(1) 检测是否是Multipart ,不是则返回当前的http request

         (2) 解析resolveMultipart(request) 返回默认的 DefaultMultipartHttpServletRequest

    检测逻辑进入到了org.apache.commons.fileupload.servlet.ServletFileUpload 检测POST 方法,判断ContentType 是multipart;  

  到这里我们的HttpServletRequest 就被包装成了 DefaultMultipartHttpServletRequest ,里面有文件的信息还有原始HttpServletRequest的信息,至于怎么获取文件的,看抛出的

  第三个问题;

    问题抛出:3  传统的fileUpload与Spring被包装后的文件上传比较:

  我们看一下使用FileUpload 上传的逻辑代码:

/**
* 在XML 中没有配置CommonsMultipartResolver解析器情况下
* 使用fileUpload 文件上传
*/ DiskFileItemFactory fileItemFactory=new DiskFileItemFactory();
//创建FileUpload
ServletFileUpload fileUpload =new ServletFileUpload(fileItemFactory);
//获取所有的文件,每一个文件信息都在FileItem 中
List<FileItem> fileItems = fileUpload.parseRequest(req);
FileItem fileItem = fileItems.get(0);//demo 只有一个文件
String fieldName = fileItem.getFieldName();
System.out.println(fieldName);
InputStream inputStream = fileItem.getInputStream();
long size = fileItem.getSize();
//.....上传逻辑,到ftp 腾讯云 等

  这种方式,在每一次上传的时候,都必须写这么一段的获取文件的逻辑

  Spring 在此之上做了一层封装,使用 CommonsMultipartResolver 进行解析(底层还是fileUolad):

  对象创建:

  创建 DiskFileItemFactory 以及ServletFileUpload 两个对象,与我们上面代码逻辑一样

  这样解析器就初始化完成了。

  我们看解析代码:

  进行parserequest(request) 将List<FileItem> 封装到了sprintg 自己的 MultiartParsingResult 对象中;

  想像的到,就是将List<FileItem> 遍历,进行组合

  每一个文件都是一个 CommonsMultipartFile,也就是我们在controller 方法定义的MultipartFile  其实就是CommonMultipartFile

  将MultiartParsingResult 参数融合到一块,就形成了 DefaultMultipartHttpServletRequest 对象;在这个对象里就可以拿到你上传到文件;

  介绍DefaultMultipartHttpServletRequest几个方法吧:

  @RequestMapping("upload")
public void upload( MultipartFile file, HttpServletRequest req)throws Exception{ DefaultMultipartHttpServletRequest request=(DefaultMultipartHttpServletRequest)req;
//得到所有的文件名
Iterator<String> fileNames = request.getFileNames();
//得到所有的文件名与文件流的映射ma p
MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
//通过名字得到MultipartFile 对象,其实就是CommonsMultipartFile
MultipartFile file2 = request.getFile("file");
//得到MultipartFile 对象就可以得到输入流
InputStream fileStream = file.getInputStream();
//文件名
String filename = file.getOriginalFilename();
//文件后缀
String suff =filename.substring(filename.lastIndexOf(".")+1); }

  参数解析的时候,也就是用的上面这些方法,拿到MultipartFile 的;Spring参数解析请看我以后的文章

  嗯,就结束了,哈哈

Spring 文件上传MultipartFile 执行流程分析的更多相关文章

  1. Hadoop之HDFS原理及文件上传下载源码分析(下)

    上篇Hadoop之HDFS原理及文件上传下载源码分析(上)楼主主要介绍了hdfs原理及FileSystem的初始化源码解析, Client如何与NameNode建立RPC通信.本篇将继续介绍hdfs文 ...

  2. spring文件上传

    Spring文件上传 1,导包: <dependency> <groupId>javax.servlet</groupId> <artifactId>s ...

  3. Spring文件上传出错:java.lang.ClassCastException: org.apache.catalina.connector.Request

    java.lang.ClassCastException: org.apache.catalina.connector.RequestFacade cannot be cast to org.spri ...

  4. SpringMVC 文件上传 MultipartFile

    本的SpringMVC的搭建在我的上一篇文章里已经写过了,这篇文章主要说明一下如何使用SpringMVC进行表单上的文件上传以及多个文件同时上传的步骤 SpringMVC 基础教程 框架分析:http ...

  5. Spring文件上传配置

    增加依赖jar包 <dependency> <groupId>commons-fileupload</groupId> <artifactId>comm ...

  6. Spring 文件上传功能

    本篇文章,我们要来做一个Spring的文件上传功能: 1. 创建一个Maven的web工程,然后配置pom.xml文件,增加依赖: <dependency> <groupId> ...

  7. Hadoop之HDFS原理及文件上传下载源码分析(上)

    HDFS原理 首先说明下,hadoop的各种搭建方式不再介绍,相信各位玩hadoop的同学随便都能搭出来. 楼主的环境: 操作系统:Ubuntu 15.10 hadoop版本:2.7.3 HA:否(随 ...

  8. (转)Spring文件上传,包括一次选中多个文件

    背景: http://www.cnblogs.com/lixuwu/p/8495275.html已经实现了单文件的上传和下载,多文件的上传是另一种情景,这里记录下来 实现过程 先说前台. 运行以后就是 ...

  9. Spring文件上传Demo

    package com.smbea.controller; import java.io.File; import java.io.FileOutputStream; import java.io.I ...

随机推荐

  1. php对函数的引用

    function &example($tmp=0){                  //定义一个函数,别忘了加“&”符     return $tmp;              ...

  2. sqlserver 已星期一为第一天统计周

    本文来源:https://blog.csdn.net/sqlserverdiscovery/article/details/53080695 SELECT GETDATE() AS THEDAY, c ...

  3. [php]php设计模式 (总结)

    转载自[php]php设计模式 (总结) 传统的23种模式(没有区分简单工厂与抽象工厂) http://www.cnblogs.com/bluefrog/archive/2011/01/04/1925 ...

  4. 自己的mongodb的CRUD封装

    工具类:package Utils; import com.google.common.collect.Lists; import com.mongodb.MongoClient; import co ...

  5. solr参数之facet

    facet就像sql语句中的group一样,是对某一个字段进行group并count,即能够按照Facet的字段进行分组并统计. 一.基本使用: 必须属性:facet=true&facet.f ...

  6. 2018-2019-2 20165205 《网络对抗技术》 Exp1 PC平台逆向破解

    2018-2019-2 20165205 <网络对抗技术> Exp1 PC平台逆向破解 1. 实验任务 1.1实验概括 用一个pwn1文件. 该程序正常执行流程是:main调用foo函数, ...

  7. iis7.5 配置伪静态

    1)首先新建一个应用程序池,名称任意,比如:nettest,托管管道模式先暂时设置为集成模式,等下面的一系列设置完成之后再设置成经典模式: 2)部署好站点,并将此站点的应用程序池设置为nettest; ...

  8. tornado架构分析1 从helloworld分析tornado架构

    最近公司需要我写一个高性能RESTful服务组件.我之前很少涉及这种高性能服务器架构,帮公司和平时没事玩都是写脚本级别的东西.虽然好多基础组件(sphinx.logging.configparse等) ...

  9. 深入理解Java虚拟机读书笔记6----早期(编译期)优化

    六 早期(编译期)优化   1 “编译期”的含义     · 可能是指一个前端编译器把*.java文件转变成*.class文件的过程,前端编译器如:Sun的Javac.Eclipse JDT中的增量式 ...

  10. FI-盘盈盘亏借贷科目

    资产的盘盈盘亏一般分两步:第一步,批准前调整为账实相符:第二步,批准后结转处理.库存现金.存货.固定资产.工程物资的盘盈盘亏的账务处理见下图: 以上科目中可能并不完整,比如“原材料等科目”就可能包括“ ...