commonFileUpload处理上传文件和HTTP文件上传协议


//判断表单是否是Multipart类型的。这里可以直接对request进行判断 
if (ServletFileUpload.isMultipartContent(request)) {
    // 创建文件处理工厂,它用于生成 FileItem 对象。 
    DiskFileItemFactory factory = new DiskFileItemFactory(); 
     //设置文件的缓存路径
       String tempdir =this.getServletContext().getRealPath("/upload/temp");    
     java.io.File d = new java.io.File(savedir);
        if(!d.exists()){
         d.mkdirs();
        }
      
    factory.setSizeThreshold(1024*1024); // 设置最多只允许在内存中存储的数据,单位:字节
    factory.setRepository(d); // 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录(默认可以不用设置)
 
    // Create a new file upload handler
    ServletFileUpload upload = new ServletFileUpload(factory);
    // 设置允许用户上传文件大小,单位:字节
    upload.setSizeMax(yourMaxRequestSize);
    //上传文件,并解析出所有的表单字段,包括普通字段和文件字段
    List  items = upload.parseRequest(request); 
         //下面对每个字段进行处理,分普通字段和文件字段
   Iterator it = items.iterator();
   while(it.hasNext()){
    FileItem fileItem = (FileItem) it.next();
    //如果是普通字段
    if(fileItem.isFormField()){  //是普通的字段
     System.out.println(fileItem.getFieldName() + "   " + fileItem.getName() + "   " + new String(fileItem.getString().getBytes("iso8859-1"), "gbk"));
    fileItem.getFieldName();//得到字段name属性的值
    fileItem.getName();//得到file字段的文件名全路径名,如果不是file字段,为null
    fileItem.getString();//得到该字段的值,默认的编码格式
    fileItem.getString("UTF-8");//指定编码格式
    }else{//文件字段
         System.out.println(fileItem.getFieldName() + "   " +
        fileItem.getName() + "   " +//得到file字段的文件名全路径名
        fileItem.isInMemory() + "    " +//用来判断FileItem类对象封装的主体内容是存储在内存中,还是存储在临时文件中,如果存储在内存中则返回true,否则返回false
        fileItem.getContentType() + "   " +//文件类型
        fileItem.getSize());          //文件大小
 
       //什么东西都有了 ,想怎么处理都可以了
     //保存文件,其实就是把缓存里的数据写到目标路径下
     if(fileItem.getName()!=null && fileItem.getSize()!=0){
      File fullFile = new File(fileItem.getName());
      File newFile = new File("c:/temp/" + fullFile.getName());
      try {
       fileItem.write(newFile);
      } catch (Exception e) {
       e.printStackTrace();
      }
     }else{
      System.out.println("文件没有选择 或 文件内容为空");
     }





HTTP协议RFC1867介绍:


RFC1867协议主要是在HTTP协议的基础上为INPUT标签增加了file属性,同时限定了Form的method必须为POST,ENCTYPE必须为multipart/form-data。还增加了一些与此相关的属性。 



HTTP协议的简单介绍

一般说来我们认为HTTP协议是构建在TCP/IP之上的协议,其实HTTP协议本身无此限制,但因现实中多数情况均是如此,我们就姑且如此认为。HTTP数据总体说来分三大部分:

(1)        请求行,如下格式

(Request) POST SP URL SP HTTP/1.1 /r/n

请求方法+空格+请求URL+空格+HTTP协议版本+回车换行

如:POST http://localhost:8080/test/test.jsp HTTP1.1/r/n

 

 

(Response)HTTP/1.1 SP 200 SP OK /r/n

HTTP协议应答版本+空格+状态码+状态描述+回车换行

如:HTTP/1.1 200 OK /r/n

 

 

请求行主要是描述请求的URLHTTP协议版本,应答状态等信息。

(2)        请求头

HttpServletRequest接口里已经封装了对HTTP头操作的方法。如Content-typeContent-lengthUser-Agent,Host等都是HTTP头。HTTP头主要描述了HTTP所传输数据的一些信息,如主机,数据内容类型,数据长度,代理类型等。

如:

User-Agent: myselfHttp/1.1/r/n

Accept: www/source; text/html; image/gif; */*/r/n

HTTP+:+空格+头信息+回车换行

(3)        HTTP实体

HTTP实体存放着,HTTP请求的内容,如参数信息,文本框的内容,隐含控件的值,ListBox的值等。如果在页面上存在:

<input type=”text” name=”userName” value=”zhangsan”>

<input type=”password” name=”password” value=”123”>

HTTP实体会出现以下形式:(POST提交)

userName=zhangsan&password=123

GET提交的时候需要解析HTTP请求行中的URL,在此不多作讨论。

 

 

      RFC1867协议的数据格式

(1)      RFC1867HTTP头的变更

RFC1867HTTP头作了适当地变更,但变更很小。首先content-type头由以前的:

content-typeapplication/x-www-form-urlencoded

变为

content-typemultipart/form-data; +空格+

boundary=---------------------------7d52b133509e2

 

 

即增加了boundary,所谓的boundary其实就是分割线,下文将看到,RFC1867利用boundary分割HTTP实体数据。boundary中数字字符区是随机生成的。

 

 

(2)      HTTP实体的变更

因为RFC1867增加了文件上传得功能,而上传文件内容自然也会被加入到HTTP的实体中。现在因为既有HTTP一般的参数实体,又有上传文件的实体,所以用boundary把每种实体进行了分割,HTTP的实体看起来将是下面的样子:


 

 

-----------------------------7d52b133509e2

Content-Disposition: form-data; name="file1"; filename="c:/aa.txt"

Content-Type: text/plain

 

 

文件内容在此处

-----------------------------7d52b133509e2

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

 

 

zhangsan

-----------------------------7d52b133509e2

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

 

 

123

-----------------------------7d52b133509e2—

 

 

很明显,增加了文件上传后,HTTP实体变得稍微复杂了,首先是通过boundary把实体分开,以便于读取,然后对FileUpload的格式也作了限制。

(3)      RFC1867协议的数据格式

根据RFC1867协议,在HTTP实体中必须对每个上传得文件有说明头,如:

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

 filename="c:/aa.txt"

 

 

Content-Disposition:指明内容类型是form-data

name="file1":指明页面上<input type=”file”>标签的名字是file1

filename="c:/aa.txt":指明上传文件在客户端上的全路径

空行:文件头说明完毕后,要加一空行,以表示后面的数据是文件的内容

文件内容:再接下来就是文件的内容

 

 

从这个角度说,完全可以利用HTTP协议+RFC1867协议开发基于文档管理应用程序。






部分转载自:http://www.cnblogs.com/yezhenhan/archive/2011/01/05/1926482.html



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值