当前位置:网站首页 > 技术博客 > 正文

文件上传解决方案



重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。

本文更新不及时,请到原文地址浏览:《超详细的实现上传文件功能教程,文件上传实现。》。

一、文件上传的方式

在程序的世界里,没有什么功能的实现方式是单一的。上传文件也不例外,我们有很多种能够实现文件上传的方法。但我们最终要采用的,必然是最熟悉、最常用的方法。文件上传通常有下面的方法进行:

  1. 将内容进行base64,将base64字符串结果通过普通请求提交给后台。
  2. 直接使用浏览器的form表单进行文件上传。
  3. 使用java模拟表单(自己封装表单格式数据)进行文件上传。

这些文件上传方式,都是基于HTTP协议的基础,它并没有强制限定了我们要如何去编码或处理数据,相反协议的存在使世界上所有的程序差异化不是那么太大。HTTP协议规定了,提交大量数据时,可以使用请求来进行提交。是的,大多数后台程序都只会在请求下去获取大量上传的数据,而不会在请求下去获取。你要知道,如果你不规范提交,当然也是可以不规范的从下获取到提交的数据。但极其不建议这样做。

如果你对HTTP协议还不是很了解,你可以通过这篇文章来入门对HTTP协议的了解:《【HTTP,Java】认识HTTP协议,在互联网世界里翱翔》。

二、base64 上传文件

1、HTML网页内使用base64

如果你要在网页中使用base64的方式将文件提交给后台,那么你不得不面临一个很严峻的问题就是:如何在网页中奖文件内容读取并转换成base64的数据。很幸运为我们提供了解决方案。

提供了读取文件的能力。但它可不是你想象的提供一个文件路径就可以读取了。它能读取的文件需是来自下面的途径:

  1. 通过节点选择的文件。
  2. 通过拖放()文件事件得到的文件。
  3. Canvas通过方法返回的文件。

下面以选择的文件为例进行讲解。

a、选择文件并转换为base64

直接在html文件中写一个并将其type设定为file即可立即实现一个文件选择功能。现在同时给出读取文件的示列代码:

 

上述代码中详细注释了使用如何读取文件的使用方式。通过监听事件,即可获取到文件读取的结果数据。如果你将这个结果打印出来,你将看到类似下面的数据:

 

如果你看到了类似的数据。那么你就算是成功一半了。

注意: 其中这一段属于对base64数据体的描述。文件真实base64内容只有逗号后面部分。如果后端接口明确告知你只需要传递后面的数据,那么你还需要自行将前面的描述去除。

b、上传结果到接口

现在建立请求将得到的结果提交到服务器即可。在监听事件里我们可以成功的获取到base64的结果,因此只需要将提交数据代码写在监听里即可。这里我直接使用的方法进行数据提交。代码如下:

 

如果你对的post方法不是很熟悉,请参考:【JQuery】JQuery常用方法总结、大全。

2、Java程序内使用base64

在使用java作为后台程序的时候,有时候也经常通过http向其他服务器上传内容,那如果是使用base64方式,如何将数据以base64提交呢?其实非常简单,和上一小节里提到的有点类似,Java里还有一个类,他可以方便的将文件转为一个base64字符串,看下面的示列代码:

 

有了base64字符串,就可以方便的进行上传了。相信后台程序一般都会有一个封装好了的网络请求工具类,下面示列一个典型的上传代码:

 

此处使用的工具你可以通过下面的maven依赖获取:

 
3、后台接口

上述请求中,将数据以 base64Data 字段提交给了接口。现在只需要处理服务器响应后的事情了。先看看接口是如何获取数据的把:

 

三、form表单上传文件

对于前端来说,这种方式无疑是最简单的上传方式,因为甚至可以做到不写一点JavaScript代码就实现了。为了对前端上传文件有更深入了解,使用form表单上传时也有两种上传方案,一种是直接使用form节点的,另一种则是通过对象来完成。

1、使用html的form节点

下面直接展示示列代码:

 

这样,前端就实现了文件上传了。提交给接口要怎么去获取里面的文件,前端不用管了。

2、使用 FormData 对象

当使用完成文件上传时,事情就变得稍微复杂一点了。但是有它的优势。直接在页面上使用form表单会造成页面的跳转,上传成功后就不会再停留在当前页面了。而使用 进行文件上传则可以完成异步上传,达到不跳页面的效果。

首先要清除一点,对象要提交数据时,其文件数据是来自于选择的文件。加入现在你已经选好了文件并且拿到了对象,那么下面示列一个如何将此数据上传到服务端的代码:

 

代码中可以看到,首先使用 创建了一个实例,然后将文件和描述信息放入其中,最后通过 的 ajax 方法将数据提交给后台接口。

四、使用Java模拟表单

java里没有类似的上传文件辅助类,我们需要根据表单在上传文件时数据具体是如何进行提交的流程进行自己使用java来实现。摆在我们面前的首要任务就是要搞明白表单提交的数据结构,只有详细了解了其结构,才能使用Java进行完美的模拟。

1、文件上传的数据内容格式

通过表单上传文件显然是HTTP协议内的一部分内容,因此我们不妨直接翻开HTTP协议里针对表单上传文件相关的定义文档:RFC1867。下面是一些重点内容的截取部分(博主能力有限,翻译得不好还请将就凑合):

multipart/form-data的定义

数据格式内容举例

ww

2、Java代码实现表单

通过上述HTTP协议定义文档中的描述,相信文件表单在数据提交过程中数据传输方式和格式已经有了大致的了解。现在是时候使用Java实现这样一个功能了。

a、单个表单文件单元

根据定义,一个input可以支持选择多个文件的,而在传输时,每个文件的传输需要提供一些基本信息。因此,直接为单个文件单元实现为一个类:

 
b、Input单元

input单元里可以放置一个键值对,用来传递数据,同时,它还可以传递键和一系列文件,上一节的文件单元就可以放在这个Input单元中。则可以设计出 Input单元类如下:

 
c、 form 表单

实现了 Input 之后,最后一个便是form实现了,form只需要实现其基本的数据组装即可完成:

 
d、测试结果

现在、、 类都已完成开发,不妨进行一下测试:

 

完美通过。

e、附加类

在上述几个类中,使用了一个常量类,其代码如下:

 

五、后台接收表单文件

本文主要讲了Java后台如何实现获取表单内的数据,下面将分别对spring后台和原生的servlet后台进行示例。

1、Spring后台

如果你的后台使用了Spring框架,那么你就幸运了,你可以十分方便的拿到表单上传上来的文件。只需要通过一些简单的注解就可以完成,下面示列了一个典型的Controller接口方法,用于获取表单上传上来的文件:

 

这个方法针对input里只有一个文件时非常方便。如果某个input里包含了多个文件,这个方法似乎没法获取到更多的文件。(如果这个方法能的法话,还请大佬评论指正。)

当你希望获取到某个input下的所有上传的文件时。你可以用下面的方法:

 
2、servlet 实现

在servlet中获取表单上传的文件相对比spring里复杂,但其实spring只是把servlet的封装了一下。咱们java后台的表单解析功能是自带就有的。下面给出一个示例:

 

六、总结

无论使用什么方式进行文件上传,只要对HTTP协议有一定的了解,都可以轻松完成各种需求的开发。为什么要针对表单进行模拟来上传文件,因为这是大多数服务器的上传文件方式,许多服务端也都默认支持解析表单文件,因此客户端的上传也许迎合服务器所支持的使用表单进行文件上传。

如果你还对HTTP协议不是很了解,可通过这篇文章进行入门:《【HTTP,Java】认识HTTP协议,在互联网世界里翱翔》。

版权声明


相关文章:

  • 数据结构快速排序图解2025-04-12 12:30:00
  • 命令行选项语法错误类型命令/帮助2025-04-12 12:30:00
  • knn算法百度百科2025-04-12 12:30:00
  • 如何在html中引入javascript代码2025-04-12 12:30:00
  • iic的通信协议2025-04-12 12:30:00
  • csdn积分获取攻略2025-04-12 12:30:00
  • shell脚本加密三种方法2025-04-12 12:30:00
  • 字典树查询时间复杂度2025-04-12 12:30:00
  • 单臂路由原理与配置2025-04-12 12:30:00
  • if指令的中文意思是2025-04-12 12:30:00