文件上传之 commons-fileupload(二)

对commons fileupload上传组件的简单封装

在上一篇文章《 利用Jakarta commons fileupload组件实现多文件上传 》中,我介绍了commons fileupload组件的基本原理和实现方法。但是在实际操作中,我们需要分析每个FileItem,然后从该FileItem中读取该控件的name和value,显然这不符合我们的习惯。比如我们在页面上有个text文本框:
< input  type ="text"  name ="possess" >

我们要取得possess传过来的value,一般我们是这么写的:
String possess  =  request.getParameter( " possess " )

但是在commons fileupload中我们却需要这么处理:
        DiskFileItemFactory factory  =   new  DiskFileItemFactory();
        
// Create new file upload handler
        ServletFileUpload upload  =   new  ServletFileUpload(factory);
        String possess 
=   "" ;
        
try   {
            List items 
= upload.parseRequest(request);
            Iterator iterator 
= items.iterator();
            
while(iterator.hasNext()){
                FileItem item 
= (FileItem)iterator.next();
                
if(item.isFormField())                   
                    String fieldName 
= item.getFieldName();
                    String value 
= item.getString();
                    
if(fieldName.equals("possess")){
                       possess value;
                    }

                }

            }

        }
  catch  (FileUploadException e)  {
            e.printStackTrace();
        }

按照上面处理的话,很是不爽,因此我想包装一下,使得使用起来符合我们的习惯。
总体设计思想:
1.我们可以像以前那样,传入控件的name,就可以取得该控件的value,因此我想可以遍历所有FileItem,然后把他们存入一个Map中(key中存入fieldname,value中存入该控件的value),这样就可以达到以上目的了。
2.在该包装类中,我们还要可以设置一些值,从而我们可以更改commons fileupload中的一些配置。
具体实现:
     根据以上要求,我写出了一个MutiFileUpload类,代码如下,稍后再做详细解释。
package  chb.commons.fileupload.web;
import  java.util.HashMap;
import  java.util.Iterator;
import  java.util.List;
import  java.util.Map;
import  javax.servlet.http.HttpServlet;
import  javax.servlet.http.HttpServletRequest;
import  org.apache.commons.fileupload.FileItem;
import  org.apache.commons.fileupload.FileUploadException;
import  org.apache.commons.fileupload.disk.DiskFileItemFactory;
import  org.apache.commons.fileupload.servlet.ServletFileUpload;


public   class  MutiFileUpload  extends  HttpServlet {
    
private static final long serialVersionUID = 670829239023754119L;
    
    
protected Map<String, String> parameters;//保存普通form表单域
    protected Map<String, FileItem> files;//保存上传的文件
   
    

    
private int sizeThreshold = DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD;
   
    


  
private long sizeMax = -1;
    
    
private String encoding = "utf-8";//字符编码,当读取上传表单的各部分时会用到该encoding

    
public String getEncoding() {
        
return encoding;
    }


    
public void setEncoding(String encoding) {
        
this.encoding = encoding;
    }


    
public long getSizeMax() {
        
return sizeMax;
    }


    
public void setSizeMax(long sizeMax) {
        
this.sizeMax = sizeMax;
    }


    
public int getSizeThreshold() {
        
return sizeThreshold;
    }


    
public void setSizeThreshold(int sizeThreshold) {
        
this.sizeThreshold = sizeThreshold;
    }


    
public void parse(HttpServletRequest request){

        parameters 
= new HashMap<String, String>();
        files 
= new HashMap<String, FileItem>();
        
//Create factory for disk-based file items

       DiskFileItemFactory factory 
= new DiskFileItemFactory();
        
//Set factory constraints
        factory.setSizeThreshold(sizeThreshold);

        
//factory.setRepository(repository);
        
//Create new file upload handler

        ServletFileUpload upload 
= new ServletFileUpload(factory);
        
//Set overall request size constraint

        upload.setSizeMax(sizeMax);
        upload.setHeaderEncoding(encoding);
        
try {
            List items 
= upload.parseRequest(request);
            Iterator iterator 
= items.iterator();
            
while(iterator.hasNext()){
                FileItem item 
= (FileItem)iterator.next();
                
if(item.isFormField())                   
                    String fieldName 
= item.getFieldName();
                    String value 
= item.getString();

                    parameters.put(fieldName, value);
               }
else{
                   String fieldName 
= item.getFieldName();
                    files.put(fieldName, item);

                }

            }

        }
 catch (FileUploadException e) {

            e.printStackTrace();

        }


    }


    

    
public String getFileName(FileItem item){

        String fileName 
= item.getName();
        fileName 
= replace(fileName,"\\","/");
        fileName 
= fileName.substring(fileName.lastIndexOf("/")+1);
        
return fileName;
    }


    


    
public static String replace(String source, String oldString, String newString) {

        StringBuffer output 
= new StringBuffer();
        
int lengthOfSource = source.length(); 

        
int lengthOfOld = oldString.length(); 

        
int posStart = 0

        
int pos; 
        
while ((pos = source.indexOf(oldString, posStart)) >= 0{
            output.append(source.substring(posStart, pos));
            output.append(newString);
            posStart 
= pos + lengthOfOld;
        }


        
if (posStart < lengthOfSource) {
            output.append(source.substring(posStart));
        }


        
return output.toString();
    }


}



                 以上代码很简单,看过commons FileUpload组件API的程序员,应该都能看明白。值得注意一下的是:编码问题(setHeaderEncoding),这个方法是从 FileUploadBase类里继承的, 根据其说明,当读取上传表单的各部分时会用到该encoding,如果没有指定encoding则使用系统缺省的encoding。建议在这里设置成utf-8,并把jsp的charset也设置成utf-8,否则可能会出现乱码。
测试demo
        好了,下面我就写个简单的demo吧,说明一下MutiFileUpload的用法。
       1.新建一个jsp页面,注意设置form表单的enctype,如下:
   < form  id ="form1"  method ="post"  action ="../servlet/UploadServlet"  enctype ="multipart/form-data" >
                
                
< tr >
                    
< td  width ="25%"  align ="right" > 上传图片: </ td >
                    
< td >                             
                        
< input  id ="file1"  type ="file"  NAME ="file1"  style ="width:300px;" >                                                       
                    
</ td >
                
</ tr >
                
< tr >
                    
< td  width ="25%"  align ="right" > 上传音频: </ td >
                    
< td >                             
                        
< input  id ="file2"  type ="file"  NAME ="file2"  style ="width:300px;" >                                                     
                    
</ td >
                
</ tr >
                
< tr  align ="center"  valign ="middle" >
                    
< td  height ="60"  colspan ="2" >
                        
< input  type ="submit"  id ="BtnOK"  value ="确认上传" >
  
< button  onclick ="javascript:window.opener == null;window.close();" > 取消上传 </ button >   </ td >
                
</ tr >
                
< tr  align ="center"  valign ="middle" >
                    
< td  height ="60"  colspan ="2" >
                         
< input  type ="text"  name ="possess"  value ="private" >
                    
</ td >
                
</ tr >
        
</ form >
     2.新建一个UploadServlet并继承自 MutiFileUpload,如下:

public   class  UploadServlet  extends  MutiFileUpload  {
}
     
3.然后在post方法中如下处理:
     public   void  doPost(HttpServletRequest request, HttpServletResponse response)
            
throws  ServletException, IOException  {
        
        parse(request);
        System.out.println(parameters.get(
"possess"));
        Iterator iterator 
= files.values().iterator();
        
while(iterator.hasNext()){
            FileItem item 
= (FileItem) iterator.next();
            String fileName 
= getFileName(item);
            File file 
= new File("/root/upload/",fileName);
            
try {
                item.write(file);
            }
 catch (Exception e) {
                e.printStackTrace();
            }

        }

    }
     选择上传文件,然后我们就可以在/root/upload下看到我们上传的文件了。
        好了,先写到这里吧,具体应用时,我们可能需要很多变通,比如集成到spring,hibernate中,关键是给出一个想法,我们可以对他进行包装变更,使其更适合我们的系统。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值