在上传文件中用commons-fileupload

问题:

当在表单form中设置 multipart/form-data

如:

<form action="userfile.jsp" method="post"   enctype="multipart/form-data">
		<p><input type="text" name="user" size="20"> </p>
		<p><input type="text" name="password" size="20"> </p>
		<p> <input type="file" name="ff"></p>
		<p><input type="submit" value="tt" ></p>
	</form>

在userfile.jsp中用
 String user=request.getParameter("user");
    String password=request.getParameter("password");
是获取不了参数的。 将返回null

为什么会这样呢???

enctype="multipart/form-data"是上传二进制数据; form里面的input的值以2进制的方式传过去。
form里面的input的值以2进制的方式传过去,所以request就得不到值了

所以我们可以用二进制文件流进行处理解析  request.getInputStream();

可以参考:http://www.oschina.net/code/snippet_117676_4588

 public String getParameter(ServletInputStream in)// 只能按顺序提取
068             throws Exception
069     {
070         int l = 0;
071         byte[] b = new byte[1024];
072         l = in.readLine(b, 0, b.length);// 依次是读取属性的开始符、名称、属性值的类型、属性的值
073         String si = new String(b);
074         if (si.startsWith("----------------------------"))
075         {// 表示是从开始符开始读,否则应为刚读取文件后的一个属性,此时应少读一次
076             l = in.readLine(b, 0, b.length);
077         }
078         l = in.readLine(b, 0, b.length);
079         l = in.readLine(b, 0, b.length);
080         String value = new String(b, 0, l);
081         return value;
082     }
083  
084     public long getFileUpload(ServletInputStream in, String fpath)// 需要提供输入流和存储路径
085             throws Exception
086     {
087         // out.println("文件信息:<br>");
088         long begin = System.currentTimeMillis();// 传送时间计时开始
089         int l = 0;
090         byte[] b = new byte[1024];
091         l = in.readLine(b, 0, b.length);
092         String sign = new String(b, 0, l);// eg.-----------------------------7d9dd29630a34
093         l = in.readLine(b, 0, b.length);
094         String info = new String(b, 0, l);// eg.Content-Disposition:form-data;
095         // name="file";
096         l = in.readLine(b, 0, b.length);
097         // String type=new
098         // String(b,0,l);//eg.Content-Type:application/octet-stream(程序文件)
099         l = in.readLine(b, 0, b.length);
100         // String nulll=new String(b,0,l);//此值应为空
101  
102         int nIndex = info.toLowerCase().indexOf("filename=\"");
103         int nLastIndex = info.toLowerCase().indexOf("\"", nIndex + 10);
104         String filepath = info.substring(nIndex + 10, nLastIndex);
105         int na = filepath.lastIndexOf("\\");
106         String filename = filepath.substring(na + 1);
107         // out.println("文件绝对路径:"+filepath+"<br>");
108         // out.println("文件名:"+filename+"<br><br>");
109  
110         String path=fpath + filename;
111          
112         File fi = new File(path);// 建立目标文件
113         if (!fi.exists()&&!fi.createNewFile())
114             return -2;
115         BufferedOutputStream f = new BufferedOutputStream(new FileOutputStream(
116                 fi));
117  
118         while ((l = in.readLine(b, 0, b.length)) > 0)
119         {
120             if (l == sign.length())
121             {
122                 String sign1 = new String(b, 0, sign.length());
123                 // out.println(sign1+"<br>");
124                 if (sign1.startsWith(sign))// 比对是否文件已传完
125                     break;
126             }
127             f.write(b, 0, l);
128             f.flush();
129         }
130         f.flush();
131         f.close();
132         long end = System.currentTimeMillis();// 传送时间计时结束
133         // out.println("上传文件用时:"+(end-begin)+"毫秒<br>");
134         return end - begin;
135     }

在jsp目标页面中调取


32         <%
33             ServletInputStream in = request.getInputStream();
34             upload.setInputStream(in);
35             String nam = upload.getParameter();
36             out.println("姓名:" + nam + "<br><br>");
37  
38             long time = upload.getFileUpload();
39             out.println("文件上传完毕,总共耗时:" + time + "毫秒<br>");
40  
41             String leixing = upload.getParameter();
42             out.println("文件类型:" + leixing + "<br>");
43             in.close();
44         %>
45  



但是这样也不多方便

采用commons-fileupload


FileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload upload = new ServletFileUpload(factory);
    upload.setHeaderEncoding("UTF-8");
    List items = upload.parseRequest(request);
    Iterator itr = items.iterator();
    //System.out.println((String)itr.next());
    while (itr.hasNext()) {
    	
    	FileItem item = (FileItem) itr.next();
    	String fileName = item.getName();
    	System.out.println(fileName);
    	long fileSize = item.getSize();
    	if (!item.isFormField()) {
    		//检查文件大小
    	//	判断FileItem类对象封装的数据是否属于一个普通表单字段,还是属于一个文件表单字段。
          // 普通表单字段 ---- return true;
          // 文件表单字段 ---- return false;
    		if(item.getSize() > maxSize){
    		//	out.println(getError("上传文件大小超过限制。"));
    			return;
    		}
    		//检查扩展名
    		String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    		

    		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
    		String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
    		try{
    			File uploadedFile = new File(savePath, newFileName);
    			item.write(uploadedFile);
    		}catch(Exception e){
    			out.println("上传文件失败。");
    			return;
    		}

    		
    		out.println("ok");
    	}else if(item.isFormField()){在此处判断是否是表单中的值  如果是  直接取出来
    		System.out.println(">>>>"+item.getString());
    		
    	}


 参考http://mcs.sysu.edu.cn/user/longt/Article_2081
下面及个重要的类及方法
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. DiskFileUpload类
      (1)setSizeMax(long sizeMax):
            设置请求实体的最大限定值,防止客户端故意通过上传特大文件塞满服务器.
      (2)setSizeThreshold(int sizeThreshold):
            Apache文件上传组件在解析和处理上传数据中的每个字段内容时,需要临时保存解析出的数据。
      (3)setRepositoryPath(String path):
            设置setSizeThreshold方法中提到的临时文件的存放目录,这里使用绝对路径。
      (4)parseRequest(HttpServerletRequest request)
         ParseRequest(HttpServerletRequest request,int sizeThreshold,long sizeMax,String path)
         是对HTTP请求消息进行解析的入口,需要Http请求必须是"multipart/form-data"类型.
         该方法解析出Form表单中的每个字段的数据,并将它们分别包装成独立的FileItem对象加进一个List
      类型的集合对象。
     
      (5)setHeaderEncoding(String encode)
         设置编码的方法,中文乱码处理需要用此方法.中文的编码一般用"gb2312"作为参数.
  
2. FileItem 类
      (1) isFormField()
           判断FileItem类对象封装的数据是否属于一个普通表单字段,还是属于一个文件表单字段。
           普通表单字段 ---- return true;
           文件表单字段 ---- return false;
     
      (2) getName()
            用于获取文件上传字段中的含路径的文件名。
            需要注意的是用户如果没有通过文件表单传递文件,浏览器同样也会将文件字段和信息传递给服务器,
        只是文件名和文件内容部分都为空,但这个表单字段仍然对应一个FileItem对象。此时getName()返回的是
        一个空字符串"".


      (3) getFieldName()
            用于返回表单字段元素的name属性值.


      (4) write(File file)
            该方法用于将FileItem对象中保存的主题内容保存到某个指定的文件中.该方法也可以将普通表单字          段内容写入到一个文件中,但是它的主要用途是将上传的文件内容保存到本地文件系统中。


      (5) getString()方法
            用于将FileItem对象中保存的主体内容作为一个字符串返回。


      (6)getContentType()方法
            获得上传文件的类型,即文件的后缀。如果FileItem类对象对应的是普通表单字段,返回null.


      (7)delete()方法
            用来清空FileItem类对象中存放的主体内容,如果主体内容保存在临时文件中,delete方法将删除该         临时文件。
      其余API,参考:http://commons.apache.org/fileupload/apidocs/index.html


 别人的理解  (我也这样认为的)

当通过表单传递到服务器的时候,客户端浏览器会把表单相应的数据打包发送到服务器。有点web开发
经验的都知道表单对每个数据项提供一个name属性值,服务器通过访问name属性值获取客户端提供的数据。
FileUpload的核心就是解析浏览器传到服务器的http请求,把每个表单项解析出来打包成一个FileItem.
这个FileItem可以是一个普通表单项,也可以是一个文件上传表单项。服务器可以针对每个FileItem进行
处理。普通表单项可通过getString()提取主体内容,文件表单项进行文件保存操作.
   当初不理解FileUpload,还觉得很难,其实也不是很难,不懂得看看API就OK了。还有Fileupload似乎
有进行更新,在用DiskFileUpload fu = new DiskFileUpload();的时候已经出现了过时警告。不过没有关
系,慢慢研究新内容。



















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值