自从业至今,文件上传与IO流之类的调用,一直是理解比较模糊的地方,大多就这网上搜到的资料抄抄改改草草了事,内部原理一直不甚了解,今日我们通过Spring的CommonsMultipartResolver的工具类一探文件上传的秘密;

  1.首先我们先看看CommonsMultipartResolver本身:

    

    截图为CommonsMultipartResolver类的继承及接口实现关系:

    a)我们首先看看感觉最没有关系的ServletContextAware,CommonsMultipartResolver实现了setServletContext方法,当没有指定临时的上传路径时,将上传的文件保存到ServletContext默认的位置;

        @Override
public void setServletContext(ServletContext servletContext) {
if (!isUploadTempDirSpecified()) {
getFileItemFactory().setRepository(WebUtils.getTempDir(servletContext));
}
}

    b)我们再来看看MultipartResolver接口:

      

      CommonsMultipartResolver实现了截图中的三个方法,三个方法的源代码可以自己去查看,简单的说下方法的功能:

   resolveMultipart将HttpServletRequest转化为MultipartHttpServletRequest,将里面的FileItem不是表单字段的对象转换为MultipartFile;

   @Override
public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {
Assert.notNull(request, "Request must not be null");
if (this.resolveLazily) {
return new DefaultMultipartHttpServletRequest(request) {
@Override
protected void initializeMultipart() {
MultipartParsingResult parsingResult = parseRequest(request);
setMultipartFiles(parsingResult.getMultipartFiles());
setMultipartParameters(parsingResult.getMultipartParameters());
setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());
}
};
}
else {
MultipartParsingResult parsingResult = parseRequest(request);
return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(),
parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes());
}
}   

      isMultipart(HttpServletRequest request)判断HttpServletRequest请求方式是否为post方式,content-type中是否以multipart/开头;


      cleanupMultipart(MultipartHttpServletRequest request)将请求中的FileItem删除;

 

    c)最后来看看抽象类CommonsFileUploadSupport,我们比较常用的是MultipartParsingResult parseRequest(HttpServletRequest request)这个方法。

  2.CommonsMultipartResolver过程中涉及到的类:

    a)MultipartFile:在请求头为multiti/form-data时,request被转换为multipartRequest,FileItem皆为MultiPartFile;

    b)FileItem:判断一个文件是否为formfield;

    c)DiskFileItem:继承自FileItem,默认的字符集为ISO-8859-1;

    c)FileUpload:可以设置文件大小以及文件的编码格式;

    d)FileItemFactory:FileItem的创建工厂,根据fieldName,contenType,等字段创建一个FileItem;

    e)DiskFileItemFactory:实现FileItemFactory,有默认的文件缓存内存,为10k大小,当上传文件大小超过默认的10k时保存到默认的临时目录中;

  3.Spring文件上传的过程总结:

    HttpServletRequest =>MultipartHttpServletRequest =>获取MultipartFile集合

最新文章

  1. HTTP错误404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求
  2. ASP.NET - 视图状态概述
  3. LoaderManager使用详解(二)---了解LoaderManager
  4. hdu 2084 数塔 (简单dp)
  5. swift 与 指针初级使用
  6. 【开发实例】C#调用SAPI实现语音合成的两种方法
  7. 那些我用过的Android开源项目
  8. 文件和目录之chown、fchown和lchown函数
  9. VK Cup 2015 - Round 1 -E. Rooks and Rectangles 线段树最值+扫描线
  10. 使用TWebBrowser组件保存网页为html和mht文件 收藏
  11. 数据降维技术(2)—奇异值分解(SVD)
  12. iis发布网站问题-由于权限不足而无法读取配置文件,无法访问请求的页面
  13. python 如何优雅地退出子进程
  14. DNS攻击
  15. 贪吃蛇Global Java实现(二)
  16. React icon bak
  17. 最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁
  18. selenium Java-1 配置
  19. web前端之JavaScript
  20. eclipse中切换jdk版本

热门文章

  1. TP5隐藏index.php
  2. python基础---递归函数真题解析
  3. [Day3] Nginx配置Https
  4. SpringBooot- 访问时,默认有弹出认证
  5. Docker(一)简介及核心概念
  6. Leetcode86. Partition List分隔链表(双指针)
  7. Django定义全局变量
  8. vue 图片上传功能
  9. golang接口的封装
  10. goland设置go build的工作目录