• 使用commons-fileUpload组件上传文件


      在近期的一个项目中有用到commons-fileUpload组件进行实现文件上传的功能(由于没用到框架),在使用的过程中有遇到一些问题,经过自己的琢磨也算顺利地将其解决了,在这里做个记录。

      一、commons-fileUpload文件上传组件简介

        commons-fileUpload上传组件是Apache的一个开源项目,可以到http://commons.apache.org/proper/commons-fileupload/下载最新版本(该组件需要commons-io包的支持)。该组件使用方便,同样可以实现一个或多个文件的上传,也可实现限制上传文件大小等功能。

        在文件上传中,文件上传请求由有序的表单项列表组成,fileUpload能够解析上传请求,然后向应用提供一个单独的文件表单项的列表。每个这样的表单项都实现了FileItem接口,并包含例如文件名等属性。

      二、使用要求

        1、使用commons-fileUpload组件上传文件时,需要将form表单的enctype属性设置为multipart/form-data;同时还需要设置上传文件在内存中的大小,多余的部分存储在磁盘中。

        2、将相应的commons-fileUpload包和commons-io包拷贝放入到你的web工程WEN-INF/lib目录下并Add to Build Path。

      三、使用步骤

        1、首先,创建磁盘工厂DiskFileItemFactory对象,用来配置上传组件ServletFileUpload;

            DiskFileItemFactory factory = new DiskFileItemFactory();

    DiskFileItemFactory类的常用方法

    方法 返回值 描述
    setSizeThrehold() void 该方法需要传入一个int型参数,用来设置最大内存大小(byte为单位)
    setRepositoryPath()

    void

    该方法需要传入一个String型参数,用来设置临时文件目录
    getRepository() File 获取保存临时文件地址

        2、其次,创建ServletFileUpload实例,即创建上传文件的句柄。

          可通过DiskFileItemFactory实例构造ServletFileUpload对象,代码如下:

           ServletFileUpload upload = newServletFileUpload(factory); 

    ServletFileUpload类的常用方法
    方法 返回值 描述
    isMultipartContent() boolean 检查是否是一个文件上传请求
    parseRequest() List 从request对象中得到所有上传域表单

      四、使用例子(servlet部分代码)

        下面就给出一个简单的文件上传的例子。

         1、jsp部分的代码:

     1 <%@ page language="java" contentType="text/html; charset=utf-8"
     2     pageEncoding="UTF-8"%>
     3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     4 <html>
     5 <head>
     6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     7 <title>file upload demo</title>
     8 </head>
     9 <body>
    10     <form action="/servletPro/FileUpload" method="post" enctype="multipart/form-data">
    11         <table width="31%" border="0" align="center">
    12             <tr bgcolor="#CCCCCC">
    13                 <th height="26">请选择要上传的附件:</th>
    14             </tr>
    15             <tr>
    16                 <td><label>上传文件</label><input type="file" name="file" /></td>
    17             </tr>
    18             <tr bgcolor="#CCCCCC">
    19                 <td height="23"><input type="submit" name="submit" value="上传"></td>
    20             </tr>
    21         </table>
    22     </form>
    23     <%
    24         if (request.getAttribute("result") != null) {
    25             out.println("<script>alert('" + request.getAttribute("result") + "');</script>");
    26         }
    27     %>
    28 </body>
    29 </html>

        2、在项目WebContent/目录下创建一个uploadfiles文件夹用来存放上传的文件。

        3、创建一个名为FileUpload的servlet,代码如下:
        

    package com.hyman.servlet;
    
    public class FileUpload extends HttpServlet {
        private static final long serialVersionUID = 1L;
        
        private String uploadFileDir;
        
        private ServletContext sc;
        
        
        public FileUpload() {
            super();
        }
        
        @Override
        public void init(ServletConfig config) throws ServletException {
            super.init(config);
            uploadFileDir = config.getInitParameter("uploadDir");
            sc = config.getServletContext();
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            this.doPost(request, response);
        }
    
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String simpleFileName = "";
            String fileDir = sc.getRealPath("/") + uploadFileDir;
            String message = "文件上传成功!";
            if (ServletFileUpload.isMultipartContent(request)) {
                DiskFileItemFactory factory = new DiskFileItemFactory();
                factory.setSizeThreshold(20 * 1024); //20KB
                factory.setRepository(factory.getRepository());
                ServletFileUpload upload = new ServletFileUpload(factory);
                int maxSize = 2 * 1024 * 1024; //2MB
                List formlists = null;
                try {
                    formlists = upload.parseRequest(request);
                } catch (FileUploadException e) {
                    e.printStackTrace();
                }
                Iterator iterator = formlists.iterator();
                while (iterator.hasNext()) {
                    FileItem formitem = (FileItem) iterator.next(); 
                    if (formitem.isFormField()) {
                        String fieldname = formitem.getFieldName(); 
                        //这里是非上传文件的表单域,可以通过formitem.getString(fieldname)来获取相应表单字段的值
                    } else {
                        //这里是上传文件的表单域
                        String name = formitem.getName();
                        if (formitem.getSize() > maxSize) {
                            message = "您上传的文件太大,请重新选择不超过2M的文件";
                            break;
                        }
                        String fileSize = new Long(formitem.getSize()).toString();
                        if (name == null || "".equals(name) && "0".equals(fileSize)) 
                            continue;
                        int delimiter = name.lastIndexOf("\");
                        simpleFileName = delimiter == -1 ? name : name.substring(delimiter + 1);
                        File saveFile = new File(fileDir, simpleFileName);
                        try {
                            formitem.write(saveFile);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            request.setAttribute("result", message);
            request.getRequestDispatcher("FileUpload.jsp").forward(request, response);
        }
    
    
    }

        4、在web.xml中进行初始化参数配置:

     1  <servlet>
     2     <description></description>
     3     <display-name>FileUpload</display-name>
     4     <servlet-name>FileUpload</servlet-name>
     5     <servlet-class>com.hyman.servlet.FileUpload</servlet-class>
     6     <init-param>
     7         <param-name>uploadDir</param-name>
     8         <param-value>uploadfiles</param-value>
     9     </init-param>
    10   </servlet>
    11   <servlet-mapping>
    12     <servlet-name>FileUpload</servlet-name>
    13     <url-pattern>/FileUpload</url-pattern>
    14   </servlet-mapping>

      五、使用过程中遇到的一些问题及解决办法

        1、每个用户上传的文件需要存放在以用户uid通过MD5加密命名的文件夹中,即需先在uploadfiles目录下创建一个对应的文件夹再将文件存该文件夹中。

          可以如下实现:

    1 String fileDir = sc.getRealPath("/") + uploadFileDir;
    2 //创建文件夹的路径
    3 String folderName = fileDir + "328ae78f9298e9a00c9dfa673280c17d";
    4 File folder = new File(folderName);
    5 if (!folder.exists()) {
    6     folder.mkdir();
    7 }

         2、路径中的"/"改为""

            可以使用:folderName = folderName.replaceAll("/", "\\");

            路径中的""改为"/"

            可以使用:folderName = folderName.replaceAll("\\", "/");

         3、在上传文件的时候还提交了非上传文件的表单,则读取文件和其他表单数据的先后顺序跟jsp文件中表单的前后顺序有关。

         4、在项目中,可能同时上传多份文件,而这些文件的全路径需以一个特定的连接符连接起来存到数据库中。我在项目中碰到这么一个问题,只要服务器重新启动,第一次上传文件保存的路径集没错,但是之后的上传都会出现路径集中附带之前上传的文件路径...而重启服务器之后的第一次上传又不会出现这种情况。这个问题着实纠结了很久,后来看到网上有介绍说可能是缓存的问题formitem用完要调用delete()方法清空缓存,这样处理之后还是没能解决这个问题。后来突然发现自己将保存每次上传路径集的String对象定义成了当前servlet的一个成员变量!!!servlet是单例的,该servlet只要被服务器创建了就会一直保存在服务器中,所以保存每次上传路径集的String对象会将每次上传的文件全都叠加起来。

     

  • 相关阅读:
    数据中心基础设施自动化运维之puppet专项
    centos git版本服务器配置
    安装PHP出现make: *** [sapi/cli/php] Error 1 解决办法
    php5.5 yum源
    CentOS下源码安装Apache2.4+PHP5.4+MySQL5.5
    php升级到5.4
    puppet重申证书
    passwnger
    Http状态消息
    UVA 10168 Summation of Four Primes(数论)
  • 原文地址:https://www.cnblogs.com/page-of-Hyman/p/4449881.html
Copyright © 2020-2023  润新知