java文件上传的原理_JavaWeb上传原理和实现

1、介绍enctype

enctype 属性规定发送到服务器之前应该如何对表单数据进行编码。

enctype作用是告知服务器请求正文的MIME类型(请求消息头content-type的作用一样)

1、1 enctype的取值有三种

描述

application/x-www-form-urlencoded

在发送前编码所有字符(默认)

multipart/form-data

不对字符编码。每一个表单项分割为一个部件

text/plain

空格转换为 “+” 加号,但不对特殊字符编码。

1. 当enctype=’application/x-www-form-urlencoded’

4ac1c0ae62a0e8efb585846f3cb5173c.png

2.当enctype=’multipart/form-data’

aa82d2073e6bdb46931208cea18ce5df.png

7dc231f39aa0fc4aff92de0b263154ab.png

通过观察发现这个的请求体就发生了变化。这种请求体被称之为多部件请求体。

什么是多部件请求体:就是把每一个表单项分割为一个部件。

以请求头的content-type的boundary后面的一串随机字符串作为分割标识

普通表单项:

//name的意思是文本框里面name的属性值,而admin是我们输入的文本值

Content-Disposition: form-data; name="username"

admin

文件表单项

//filename的意思是:我们上传的文件名称,content-Type的意思是:MIME类型,asdasdas的意思是:文件里面的内容

Content-Disposition: form-data; name="upload"; filename="a.txt"

Content-Type: text/plain

asdasdas

3. 当enctype=’text/plain’

4479d92d20671fdce5638fe699a0d4ba.png

w3c称:空格会变成”+”加号,但是我这里没有发现,只有当get请求的时候,空格会变成”+”号

5284675cf6a4630c7492e7ae4ececeb4.png

进入正题

完成上传需要满足3个必要的条件

提供form表单,method必须是post,因为get请求的传输数据一般为2kb,不同浏览器不一样。

form表单属性enctype的必须是multipart/form-data

提供input type=”file”类的上传输入域

大致实现原理:当enctype的值是multipart/form-data时,浏览器会把每个表单项进行分割,分割成不同的部件,以boundary的值为分割标识,这个标识的字符串是随机生成的,最后一个表单项的分割标识字符串末尾会多两个”- -“,代表结束。服务端用request.getHeader(“content-type”)获取分割字符串,然后进行解析。

2feae118c1585b05f49570698905c504.png

代码实现

一、开发环境搭建

代码实现

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// 判断表单的enctype值是不是"multipart/form-data"

boolean isMultipartContent = ServletFileUpload

.isMultipartContent(request);

if (!isMultipartContent) {

throw new RuntimeException("your form is not multipart/form-data");

}

// 创建一个DiskFileItemfactory工厂类

DiskFileItemFactory factory = new DiskFileItemFactory();

// 创建一个ServletFileUpload核心对象

ServletFileUpload sfu = new ServletFileUpload(factory);

// 解析request对象,并得到一个表单项的集合

try {

List fileItems = sfu.parseRequest(request);

// 遍历表单项数据

for (FileItem fileitem : fileItems) {

if (fileitem.isFormField()) {

// 普通表单项

String fieldName = fileitem.getFieldName();

String fieldValue = fileitem.getString();

System.out.println(fieldName + "=====" + fieldValue);

} else {

//上传表单项

//得到文件输入流

InputStream is = fileitem.getInputStream();

//创建文件存储目录

String directoryRealPath = this.getServletContext().getRealPath("WEB-INF/upload");

//创建文件路径

File storeDirectory = new File(directoryRealPath + File.separator + fileitem.getName());

//使用apache commons-io包,将输入流转成文件

FileUtils.copyInputStreamToFile(is, storeDirectory);

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值