Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 355|回复: 0

[jsp学习]对commons fileupload上传组件的简单封装

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-2 05:43:11 | 显示全部楼层 |阅读模式
    在上一篇文章《利用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 a 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;


          /** */
          /**
      * @author chb
      *
      */
          

          public
          
          class
           MutiFileUpload
          extends
           HttpServlet
          ...
          {
         private static final long serialVersionUID = 670829239023754119L;
         
         protected Map<String, String> parameters;//保存普通form表单域
         protected Map<String, FileItem> files;//保存上传的文件
       
        /** *//**
          * The directory in which uploaded files will be stored, if stored on disk.
          */
         private int sizeThreshold = DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD;
       
        /** *//**
          * The maximum size permitted for the complete request, as opposed to
          * {@link #fileSizeMax}. A value of -1 indicates no maximum.
          */

       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 a factory for disk-based file items

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

             //factory.setRepository(repository);
             //Create a 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();

             }

         }

        /** *//** 得到上传文件的文件名
          * @param item
          * @return
          */
        public String getFileName(FileItem item)...{

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

        /** *//**字符串替换
         * @param source
          * @param oldString
          * @param newString
          * @return
          */

        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中,关键是给出一个想法,我们可以对他进行包装变更,使其更适合我们的系统。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-27 02:08 , Processed in 0.350156 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表