java文件上传原理

  网页表单是一个web基础设施,提供了交互接口,作为使用web技术的开发人员,了解其工作原理,是必须的功课,本文描述表单域和二进制数据一同传输并被处理.

   有关表单资料,若需要可参考http://www.htmlhelp.com/reference/html40/forms/form.html.

   在表单元素中 enctype 属性指定了传递给服务器的表单数据集编码的内容类型,它的默认值是“application/x-www-form-urlencoded”,用于通常的数据提交格式,enctype 属性有三个值: application/x-www-form-urlencoded, multipart/form-data, text/plain, 它们都属于MIME类型,关于该类型可参考http://www.ietf.org/rfc/rfc2045.txt .

上传二进制数据时需要multipart/form-data, 并必须把表单属性method设为post, ACCEPT-CHARSET属性是表单处理器能够处理的编码字符集,若没有指定该属性,表单默认是UNKNOWN,可根据需要指定为iso-8859-1 utf-8,关于已经认可的标准字符集,可参考http://www.iana.org/assignments/character-sets.

   基于javajsp演示一个上载过程,并把上载的数据向用户直接返回.其代码为:

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="java.util.*" %>

<form name="frm" enctype="multipart/form-data" method="post" action="param1.jsp">

<input type="text" name="test" value="测试"><br>

<input type="file" name="image" value="this is a image"><br>

<input type="submit" name="sub" value="upload">

</form>

</body>

</html>

   在表单中没有指定ACCEPT-CHARSET属性,在使用us-ascii编码时,表单域被处理为gb2312编码, multipart/form-data类型使用7-bit US-ASCII编码表单数据.

param1.jsp代码:

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="java.util.*" %>

<%@ page import="org.common.servlet.*" %>

<html>

<body>

<%

ServletOutputStream sos=response.getOutputStream();

int length= Integer.parseInt(request.getHeader("Content-Length"));

String contenttype=request.getContentType();

String enc=request.getCharacterEncoding();

response.setContentType(contenttype);

ServletInputStream sis= request.getInputStream();

    int count=0;

    byte[] b=new byte[2048];

    while((count=sis.read(b))!=-1){

    sos.write(b,0,count);

    }

    sos.flush();

%>

</body>

<html>

   首先该代码会报告错误: getOutputStream调用已经由getWriter执行了.不过程序仍然可以运行,在真正的应用中,把它写成servlet.就可解决.出现这个问题原因是serlvet规范指出在request上调用getOutputStreamgetWriter必须是二选一.

弹出对话框后问你是否打开或者是保存,点保存,然后打开结果你会看到:

-----------------------------7d52e 1f 4065c

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

 

 

 

 

 

简化

-----------------------------7d52e 1f 4065c

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

 

 

 

 

 

三季稻看法上

-----------------------------7d52e 1f 4065c

Content-Disposition: form-data; name="image"; filename=""

Content-Type: application/octet-stream

 

 

 

 

 

 

 

 

 

 

-----------------------------7d52e 1f 4065c

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

 

 

 

 

 

upload

-----------------------------7d52e 1f 4065c—

   当你看到这个格式文件后,应该就理解了原来文件上传的原理就这么简单.

格式规定:每一行都是以回车换行(0xd0xa 1310)界定,每一个数据实体都以类似于-----------------------------7d52e1f4065c界定,最后的用户数据终止是以实体界定符号后加了两个连字符(--).

该格式一目了然, 实体界定符之间是表单域实体,该实体的name指定的串就是表单ui组件的name.其值是 回车换行+ui组件的值.

二进制数据实体多出了filenameContent-Type以便处理.

以上格式是遵守  http://www.ietf.org/rfc/rfc1867.txt 规范的,根据这个格式,我们可以编写自己的分析器来处理上传过来的数据.

通过这个具体实例,可加深对通信程序设计的理解.尤其是通信中控制数据和用户数据的设计和处理上.

参考资料:

http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type

http://www.faqs.org/docs/htmltut/forms/index.html

http://www.htmlhelp.com/reference/html40/forms/form.html

multipart/form-data 参考 http://www.faqs.org/rfcs/rfc2388.html
原文链接: http://blog.csdn.net/keepeye/article/details/376972

你可能感兴趣的:(java文件上传原理)