文件上传:终结篇

——《火箭队》

这是第四次写与文件上传有关的文章,这一篇主要是结合最近遇到的问题,对之前的文章进行整理汇总补充,推出《文件上传:终结篇》;

ok,正文开始

1. 文件上传 —— 传输协议

Web 应用运行期间,浏览器向服务器请求的 HTTP 报文格式主要分两类:

  • application/x-www-form-urlencoded
  • multipart/form-data

application/x-www-form-urlencoded:

以key1=value1&key2=value2...格式组织请求数据,只要不涉及文件上传,完全够用。

图1:application/x-www-form-urlencoded 报文示例

multipart/form-data:

在报文中用boundary将数据分段的方式组织请求数据,只要涉及上传文件,就得用这种报文格式

图2:multipart/form-data 报文示例

2. 文件上传 —— 前端技术

文件上传的前端技术,就是如何把待上传的文件,通过 HTTP 请求,以 multipart/form-data 报文格式发送给服务器端;

2.1. Form 表单上传

图3:Form 表单上传动画

图4:Form 表单上传代码示例

总结,Form 表单上传;

传统浏览器环境(IE7/8/9): a. 支持上传完成回调机制; b. × 支持多选文件上传; c. × 支持筛选上传文件类型; d. × 支持限定上传文件尺寸; e. × 支持文件上传进度监控; 现代浏览器环境(>=IE10): a. 支持上传完成回调机制; b. 支持多选文件上传; c. 支持筛选上传文件类型; d. × 支持限定上传文件尺寸; e. × 支持文件上传进度监控;

优点:兼容性好;

缺点:能力偏弱;

2.2. Flash 控件上传

图5:Flash 控件文件上传动画

图6:Flash 控件文件上传代码示例

总结,Flash 控件上传;

传统浏览器环境(IE7/8/9): a. 支持上传完成回调机制; b. 支持多选文件上传; c. 支持筛选上传文件类型; d. 支持限定上传文件尺寸; e. 支持文件上传进度监控; 现代浏览器环境(>=IE10): a. 支持上传完成回调机制; b. 支持多选文件上传; c. 支持筛选上传文件类型; d. 支持限定上传文件尺寸; e. 支持文件上传进度监控;

优点:增强了 IE7/8/9 环境下的文件上传能力;

缺点:

(1). 要求客户端安装 Flash;

(2). Session Cookie 数据在 Chrome、Safari、Firefox环境下不能正常发送;

图7:官方对 Session Cookie 问题的说明

http://www.uploadify.com/documentation/uploadify/using-sessions-with-uploadify/

2.3. Ajax 文件上传

现代浏览器中,我们可以使用 Ajax + JS 脚本自主控制文件上传过程,具备极大的灵活性;

图8:Ajax 文件上传动画

图9:Ajax 文件上传代码示例

总结,Ajax 文件上传;

传统浏览器环境(IE7/8/9): × 传统浏览器环境中,不支持 Ajax 文件上传; 现代浏览器环境(>=IE10): a. 支持上传完成回调机制; b. 支持多选文件上传; c. 支持筛选上传文件类型; d. 支持限定上传文件尺寸; e. 支持文件上传进度监控;

优点:功能强大、可定制性强;

缺点:只能在现代浏览器环境中使用;

3. 文件上传 —— 后端技术

文件上传的后端技术,就是如何把 HTTP 请求中的 multipart/form-data 格式报文正确解析。

3.1. Apache Commons FileUpload

图10:用 commons-fileupload 解析 multipart 请求

优点:对运行环境没特殊要求;

缺点:需要依赖第三方 jar 包;

3.2. Servlet 3.x

图11:Servlet 3.x 原生接口解析 multipart 请求

优点:不必依赖第三方工具包;

缺点:对运行环境有要求,Servlet 3.x 系列;

3.3. Spring 对文件上传的处理

从 Spring3.1 开始,Spring 提供了用于处理文件上传请求的 MultipartResolver 接口,而且自带 2 个实现类:

(1). CommonsMultipartResolver: 是 Commons FileUpload 文件处理逻辑的封装(2). StandardServletMultipartResolver: 是 Servlet 3.x 文件处理逻辑的封装

Spring 并没有创造解析上传文件的新技术,只是对已有技术的封装;

图12:用 CommonsMultipartResolver 做解析器

注:由于 Commons File Upload 是从 request 的数据流中分析 multipart 请求,所以只能分析一次;如果你想自定义 multipart 请求的解析规则,那么不要定义 multipartResolver 这个 bean,否则你是解析不到数据的。

原文发布于微信公众号 - WebJ2EE(WebJ2EE)

原文发表时间:2018-08-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券