servlet文件上传(1)---》form表单的enctype属性以及上传文件请求内容

在实际应用开发中,文件上传是很常用的功能。例如,OA办公提交公文,项目测试提交测试报告,再比如基于Web的邮件系统发送邮件附件。

在早期的HTML中,表单不能实现文件的上传,在1995年RFC1867规范(即HTML中的基于表单的文件上传)对表单做出扩展,增加了表单元素<input type="file">。例如:

<form method="post" action="upload.jsp" enctype="multipart/form-data">
    <input type="file" name="file1" size="40"><p>
    <input type="submit" value="上传">
</form>

这里使用了表单一个很重要的属性---》enctype。定义了表单数据的编码规范,规定数据在发送到服务器之前应当如何对表单数据进行编码。表单enctype属性默认值是application/x-www-form-urlencoded,这种编码方案使用有限的字符集,在发送前编码所有字符。当时用了非字母和数字的字符时,必须用“%HH”代替(H表示十六进制数字),例如一个中文字符,将被表示为“%HH%HH”,这样传输数据量就会增大很多。而multipart/form-data是一种将填写好的表单内容从客户端传送到服务器端的高效方式。它不对字符编码,只是在传送数据的周围加上简单的头部来标识文件的内容。还有一种是text/plain,这种编码方案将空格转换为“+”,但是不对特殊字符(非字母和数字)编码

我们新建一个项目,里面创建一个adminImg.jsp(名字随便取),页面代码如下:

    <form action="/doudouleyuan/pages/admin/adminImg.jsp" method="post" enctype="multipart/form-data">
    	<input type="file" name="file1" size="50"/><br/>
    	<input type="file" name="file2" size="50"/><br/>
    	<input type="text" name="desc"/><p>
    	<input type="submit" value="上传"/>
    </form>

然后部署在服务器上,浏览器输入Url访问,选择好文件后,点击上传,查看发出的请求

请求头:

servlet文件上传(1)---》form表单的enctype属性以及上传文件请求内容_第1张图片

请求Request Payload,具体不知道什么含义,姑且认为是请求装载内容,也就是服务端要收到的内容

servlet文件上传(1)---》form表单的enctype属性以及上传文件请求内容_第2张图片

几个重要点:

【1】可以看到请求头的Content-Type的值是multipart/form-data,指明客户端传送的是文件内容,如果Content-Type的值不是multipart/form-data,那么可以认为这次请求不是上传文件。Content-Type还有一个属性boundary是用来指明传送内容分隔符,这个分隔符是随机的,而且不同浏览器采用的分隔符形式也是不同的。

【2】请求头Content-Length用于表明传送内容的总长度,如果服务器端要限制上传文件的大小,可以利用ServletRequest接口的getContentLength()得到请求正文的长度,然后判断是否接受客户端上传的文件内容。

【3】请求正文每一部分都有Content-Disposition报头域,它的值是form-data,属性name指明在表单中的字段名。我们可以通过判断Content-Disposition报头域是否包含filename属性来确定该部分内容是否是文件的内容。

【4】对所有的多部分MIME类型来说,每一部分都有一个可选的报头域Content-Type,默认值是text/plain,如果文件的内容是填写表单上传的话,那么文件输入就被标识为application/octet-stream,如果浏览器指导文件内容是什么类型的,就标识为相应的媒体类型,例如上面的image/jpeg。

【5】在每一部分空行之后就是上传文件的内容或表单中相应字段的值,最后的结尾是分隔符加上两个连续的连字符(--),我们在获取请求正文的文件数据时,可以通过判断分隔符之后是否有两个连续的连字符(--)确定数据处理是否完成。

【6】对于文件上传,一定是通过输入流来获取文件内容,不能使用ServletRequest接口的getParameter()方法,而需要调用ServletRequest接口的getInputStream()方法来得到输入流,然后从输入流中读取传送的内容,再根据文件上传的格式进行分析,取出上传文件的内容和表单其它字段的内容。在分析文件上传格式的时候,不能简单地进行字符串比较,因为传送的内容有可能是像图片这样的二进制数据,而不单出是字符数据


你可能感兴趣的:(文件上传,servlet)