Http上传技术的JAVA实现

nasi90

贡献于2011-04-24

字数:7242 关键词: Java开发

Http上传技术的JAVA实现 王斌 摘要:本文介绍了HTTP上传协议,分析了web上传技术的原理,最终通过一个实例给出了解决该问题的通用方法和关键源程序代码。 关键字:Web上传,JavaBean,JSP 一、引言 许多基于B/S结构的web系统都有直接通过网页上传文件的功能。Web程序员通常都是调用现成的第三方文件上传组件来实现,就JSP来说,国内使用的一般是JspSmart的JavaBean组件,目前JspSmart已经不再提供该类型组件,今后在有类似的开发需求就需要开发人员自行实现。其实,这些Beans采用的都是基于Http协议的文件上传技术,其原理及规范已在RFC文档中说明,实现并不很难。本文将通过一个实例来介绍如何编写一个JavaBean来实现Web上传技术。 二、基于Http协议的文件上传技术原理 在最初的 http 协议中,没有上传文件方面的功能。 rfc1867 (http://www.ietf.org/rfc/rfc1867.txt) 为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 web服务器 ,包括 tomcat ,已经支持此协议,可接受发送来的文件。 要上传文件,提交数据的form的enctype必须为“multipart/form-data”,method必须是“post”,同时要在form中添加type=file的input标记,如下例(行01、03、05): Line 01:
Line 02: file,name=f
Line 03:
Line 04: file,name=f1
Line 05:
Line 06: text,name=mytext
Line 07:
Line 08: checkbox, name=mycheck
Line 09: value=check1
Line 10: value=check
Line 11: value=check
Line 12: Line 13:
通过该表单,浏览器向web服务器上传一个包含文件数据的报文,报文主体格式如下: -----------------------------7d52e01220324 Content-Disposition: form-data; name="f"; filename="filename1" Content-Type: plain/Text 文件数据 -----------------------------7d52e01220324 Content-Disposition: form-data; name="f1"; filename="filename2" Content-Type: application/octet-stream 文件数据 -----------------------------7d52e01220324 Content-Disposition: form-data; name="myText" 变量值 -----------------------------7d52e01220324 Content-Disposition: form-data; name="mycheck" 变量值 -----------------------------7d52e01220324 Content-Disposition: form-data; name="mycheck" 变量值 -----------------------------7d52e01220324— 其中,-----------------------------7d52e01220324是分隔符,分隔多个文件、表单项,报文的每一行都以“\r\n”结束。我们只需编写一个Java Bean在服务器端运行,解析报文,将文件数据保存为相应的文件即可。 三、文件上传Bean的核心源码 主要包括三个类: a) Class Parameter ,每一个Parameter对象负责客户端传过来的非文件类型变量的信息存取操作,包括变量名、变量值等。 主要方法包括: public void setParaName(String name) 赋变量名 public String getParaName() 取变量名 public void addParaValue() 添加变量值(变量可以是多值变量,故变量的名值是一对多的关系) public String[] getParaValues() 取变量值,返回一组数值 b) Class UploadFile,每一个UploadFile对象描述一个文件类型数据的相关信息 主要方法包括: public void setRemotePathName(String str) 赋上传文件在客户端的路径名和文件名 public String getRemotePathName() 取上传文件在客户端的路径名 public Striang getFileName() 取文件名 public void setLocalPathName(String str) 赋上传文件在服务器端的存储路径 public String getLocalPathName() 取上传文件在服务器端的存储路径 public void setContentDisp(String str) 赋Content-Disposition 值 public String getContentDisp() 取Content-Disposition 值 public void setContentType(String str) 赋Content-Type 值 public String getContentType() 取Content-Type 值 c) Class Upload,解析上传的http报文,将要上传的文件存储到服务器端指定的路径下 主要方法包括: public void init(PageContext pc) 初始化 public Enumeration getFiles() 获取UploadFile对象集合 public int getFileCount() 获取UploadFile对象数量,即上传文件数 public Enumeration getParameterNames() 获取非文件类型变量名集合 public String[] getParameterValues(String key) 获取变量名为key的变量值 public void uploadFiles() throws Exception 上传文件 public void setPath(String path) 设置上传文件在服务器上的保存路径 Upload通过方法init来取得request对象和服务器当前路径,通过方法uploadFiles在服务器端保存文件。 由于篇幅有限,现在只介绍类Upload 中的解析报文保存文件的核心源码: 1.Upload要引用的类库 import edu.tjut.cs.minipuss.UploadFile;// 自定义的UploadFile类 import javax.servlet.jsp.PageContext; import javax.servlet.ServletRequest; import javax.servlet.ServletInputStream; import java.io.*; import java.util.*; 其中javax.servlet类包不在J2SE中,通常在我们使用的JSP服务器(如Tomcat)中会包含该类包的jar,本文所使用的服务器是Resin2.1.0,在Resin的lib目录下的jsdk23.jar即包含该类包,编译时我们在classpath中指定该jar即可。 2. 成员变量和类的初始化 1)类Upload 包括如下5个成员变量: private PageContext pageContext;//pageContext对象 private ServletRequest request;// request对象 private Vector vector;// 非文件类型数据列表 private Vector files; // 文件类型数据列表 private String savePath;// 文件上传路径 2)构造函数,用于初始化成员变量 public Upload(){ pageContext = null; request = null; vector = new Vector();// 创建列表 files = new Vector();// 创建列表 savePath = null; } 3) 初始化函数 public void init(PageContext pc){ //// 初始化 if(pc !=null){ this.pageContext = pc; this.request = this.pageContext.getRequest(); // 取服务器端当前路径为上传路径 this.savePath = this.request.getRealPath("/"); } } 3. ploadFiles函数及其调用的私有函数 1)getNoteString, 取一行报文,不含回车换行符 private String getNoteString(ServletInputStream in){ StringBuffer sb = new StringBuffer(); int c; try{ while( (c= in.read())!= -1){ char ch =(char) c; sb.append(ch); if(ch=='\n') break; } }catch(IOException e){ } //// 截取子串,去掉回车换行符 String str = sb.toString(); int endIndex = str.lastIndexOf("\r\n"); if (endIndex==-1) endIndex = str.lastIndexOf('\n'); return str.substring(0,endIndex); } 2)getLine,读取一行报文,含回车换行符 private int getLine(ServletInputStream in,StringBuffer sb){ int c=0; sb.delete(0,sb.length());// 清空 try{ while( (c= in.read())!= -1){ char ch =(char) c; sb.append(ch); if(ch=='\n') break; } }catch(IOException e){ return -1; } return c;// 若报文读完,则C=-1 } 3)getFileName,解析传入的字串,获取文件路径名 private String getFileName(String str){ //// str:Content-Disposition: form-data; name="xx"; filename="xxxx" int endIndex = str.lastIndexOf('"'); int startIndex = str.indexOf("filename")+10; return str.substring(startIndex,endIndex); } 类似函数还有getName,getContentDisp,getContentType,处理方法同上,略。 4)向非文件型数据列表添加Parameter对象,并返回该对象的引用 private Parameter addParameter(String str){ //// 若列表中有数据名=str的对象,则返回该对象的引用 int size = this.vector.size(); for(int i=0;i

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享文档获得金币 ]
2 人已下载

下载文档

相关文档