封装了 Jakarta 文件上传功能的一个类 </p>

</span></b>

作者: BeanSoft 2007-01-05 19:32 </p>

</span>

后记: 记得改了一个支持 encoding 设置的版本, 竟然找不到了.. 回家再看看, 自己的东西也没做版本管理, 挺混乱…. 回头把此文件加入 BeanSoftLib 中去. </p>

</span>

近期项目要用到文件上传功能, 先试了用 Jsp Smart upload, 结果发现一个问题: 如果上传的文件名中有汉字, 则发生无法读取参数和文件数据的错误. 后来想到 Struts 的文件上传功能在 Tomcat Weblogic 下都没有问题, 就想到用它来做上传功能, 于是到 Apache 网站下载了 Commons FileUpload 看了看, 发现虽然功能都用, 但是使用太不方便, 例如获取表单参数竟然要一个一个的遍历, 于是就动手写了一个封装类, 这个类可以方便的读取表单参数和文件项目. </p>

</span>

首先说一下参考资料:
FileUpload
主站点:
http://jakarta.apache.org/commons/fileupload/index.html
下载 FileUpload 的源码:
http://archive.apache.org/dist/jak
arta/commons/fileupload/source/

点击 commons-fileupload-1.0-src.zip 下载源码.
下载 FileUpload 的二进制包(JAR文件):
http://archive.apache.org/dist/jakarta/commons/fileupload/binaries/
在列表中点击 commons-fileupload-1.0.zip 26-Jun-2003 08:32 128K,
下载后解压缩得到的 commons-fileupload-1.0.jar 就可以放到类路径中使用了.
Apache
自己的使用指导(英文版), 强烈建议如果要深入了解如何使用的人看看这个网页:
http://jakarta.apache.org/commons/fileupload/using.html </p>

</span>

下面就是这个类的源码了(已经在源码注释中包含了使用说明了): </p>

</span>

package beansoft.jsp; </p>

</span>

</p>

 

</span>

import java.io.File; </p>

</span>

import java.io.InputStream; </p>

</span>

import java.io.UnsupportedEncodingException; </p>

</span>

import java.util.ArrayList; </p>

</span>

import java.util.Iterator; </p>

</span>

import java.util.List; </p>

</span>

import java.util.Map; </p>

</span>

import java.util.TreeMap; </p>

</span>

</p>

 

</span>

import javax.servlet.http.HttpServletRequest; </p>

</span>

</p>

 

</span>

import org.apache.commons.fileupload.FileItem; </p>

</span>

import org.apache.commons.fileupload.disk.DiskFileItemFactory; </p>

</span>

import org.apache.commons.fileupload.servlet.ServletFileUpload; </p>

</span>

</p>

 

</span>

/** </p>

</span>

 * Jakarta commons FileUpload 封装类. </p>

</span>

 * 提供: 参数读取( Tomcat 4, 5 下测试过似乎没有中文问题), 文件保存功能. </p>

</span>

 * </p>

</span>

 * NOTE: 所有的表单和页面编码都是按照GBK 来处理的. </p>

</span>

 * TODO Refactor to make encoding configable. </p>

</span>

 * </p>

</span>

 * 示例代码( JSP 页面中, 忽略了异常处理代码): </p>

</span>

 * test.htm </p>

</span>

  

</span> </p>

</span>

   Input name:
</p>

</span>

   Select a file:
</p>

</span>

   </p>

</span>

   </form> </p>

</span>

</p>

 

</span>

   test.jsp </p>

</span>

<%@ page contentType="text/html;charset=utf8" %> </p>

</span>

<%@ page import="beansoft.jsp.*, java.io.*" %> </p>

</span>

<% </p>

</span>

   JakartaFileUploadHandler uploadHandler = new JakartaFileUploadHandler(request); </p>

</span>

   // 如果是文件上传表单 </p>

</span>

   if(uploadHandler.isMultipart()) { </p>

</span>

      // 读取参数 </p>

</span>

      String parameterValue = uploadHandler.getParameter("username"); </p>

</span>

      out.println("username=" + parameterValue); </p>

</span>

      // 保存文件 </p>

</span>

      JakartaFileUploadHandler.saveFileItem(uploadHandler.getFileItem("file1"), new File("file1.txt")); </p>

</span>

   } </p>

</span>

%> </p>

</span>

</p>

 

</span>

   更多参考资料请看 Apache 的网站上的指导文章: </p>

</span>

   Using FileUpload </p>

</span>

   @link http://jakarta.apache.org/commons/fileupload/using.html </p>

</span>

 * </p>

</span>

 * @see #getParameter(String) </p>

</span>

 * @see #getParameterValues(String) </p>

</span>

 * @see #saveFileItem(FileItem, File) </p>

</span>

 * </p>

</span>

 * 这个类依赖于 Jakarta commonsfileupload1.0.zip. </p>

</span>

 * </p>

</span>

 * @author beansoft beansoftstudio@msn.com </p>

</span>

 * @version 1.01 </p>

</span>

 * 20051130 </p>

</span>

 */ </p>

</span>

public class JakartaFileUploadHandler </p>

</span>

{ </p>

</span>

    /** 文件域列表 */ </p>

</span>

  &#16
0;
private Map fileFields= new TreeMap(); </p>

</span>

    /** 表单域列表 */ </p>

</span>

    private Map formFields= new TreeMap(); </p>

</span>

    /** Check that we have a file upload request */ </p>

</span>

    private boolean isMultipart = false; </p>

</span>

    private HttpServletRequest request = null; </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 空构造器. </p>

</span>

     */ </p>

</span>

    public JakartaFileUploadHandler() { </p>

</span>

</p>

 

</span>

    } </p>

</span>

</p>

 

</span>

    </span>/** </p>

</span>

     * 根据现有参数构造一个上传处理器. </p>

</span>

     */ </p>

</span>

    public JakartaFileUploadHandler(HttpServletRequest request) { </p>

</span>

      setRequest(request); </p>

</span>

    } </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 设置 HttpServletRequest 并分析里面的表单数据. </p>

</span>

     * @param request HttpServletRequest </p>

</span>

     */ </p>

</span>

    public void setRequest(HttpServletRequest request) { </p>

</span>

       this.request = request; </p>

</span>

</p>

 

</span>

       isMultipart = ServletFileUpload.isMu
ltipartContent(request);
</p>

</span>

</p>

 

</span>

       // 如果是文件上传请求, 就提取里面的参数 </p>

</span>

       if(isMultipart) { </p>

</span>

           // Create a new file upload handler </p>

</span>

           </p>

</span>

           DiskFileItemFactory factory = new DiskFileItemFactory(); </p>

</span>

           ServletFileUpload upload = new ServletFileUpload(factory); </p>

</span>

           /* </p>

</span>

            * Nov 29 2005, set default upload encoding to UTF-8. </p>

</span>

            * Specifies the character encoding to be used when reading the headers of </p>

</span>

            * individual parts. When not specified, or null, the platform </p>

</span>

            * default encoding is used. </p>

</span>

            */ </p>

</span>

           //upload.setHeaderEncoding("GBK"); </p>

</span>

</p>

 

</span>

           try { </p>

</span>

              // Parse the request </p>

</span>

              List /* FileItem */ items = upload.parseRequest(request); </p>

</span>

</p>

 

</span>

              // Process the uploaded items </p>

</span>

              Iterator iter = items.iterator(); </p>

</span>

              while (iter.hasNext()) { </p>

</span>

                  FileItem item = (FileItem) iter.next(); </p>

</span>

</p>

 

</span>

//                String name = item.getFieldName(); </p>

</span>

//                 String value = item.getString(); </p>

</span>

</p>

 

</span>

                  if (item.isFormField()) { </p>

</span>

                      processFormField(item); </p>

</span>

                  } else { </p>

</span>

                      processUploadedFile(item); </p>

</span>

                  } </p>

</span>

              } </p>

</span>

           } catch (Exception ex) { </p>

</span>

              System.err.println("无法处理上传数据:" + ex); </p>

</span>

           } </p>

</span>

</p>

 

</span>

       } </p>

</span>

    } </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 处理表单项目. </p>

</span>

     * @param item FileItem 对象 </p>

</span>

     */ </p>

</span>

    private void processFormField(FileItem item) { </p>

</span>

        String name = item.getFieldName(); </p>

</span>

        // NOTE 文件上传统一使用 UTF-8 编码 2005-10-16 </p>

</span>

        String value = null; </p>

</span>

</p>

 

</span>

       try { </p>

</span>

           value = item.getString("GBK"); </p>

</span>

       } catch (UnsupportedEncodingException e) { </p>

</span>

       } </p>

</span>

</p>

 

</span>

        // 首先尝试获取原来的值 </p>

</span>

        Object oldValue = formFields.get(name); </p>

</span>

</p>

 

</span>

        if(oldValue == null) { </p>

</span>

           formFields.put(name, value); </p>

</s>

       } else { </p>

</span>

           // 多个值存储为 List </p>

</span>

</p>

 

</span>

           // 原来为单个值则添加现有的值 </p>

</span>

           try { </p>

</span>

               String oldString = (String)oldValue; </p>

</span>

</p>

 

</span>

               List list = new ArrayList(); </p>

</span>

               list.add(oldString); </p>

</span>

               list.add(value); </p>

</span>

</p>

 

</span>

               formFields.put(name, list); </p>

</span>

           } catch (Exception ex) { </p>

</span>

//           ex.printStackTrace(); </p>

</span>

           } </p>

</span>

</p>

 

</span>

            // 原来为多个值则添加现有的值 </p>

</span>

           try { </p>

</span>

               List list = (List)oldValue; </p>

</span>

                list.add(value); </p>

</span>

               formFields.put(name, list); </p>

</span>

           } catch (Exception ex) { </p>

</span>

//           ex.printStackTrace(); </p>

</span>

           } </p>

</span>

       } </p>

</span>

    } </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 处理文件项目, 多附件存储为 List. </p>

</span>

     * @param item FileItem 对象 </p>

</span>

     */</span> </p>

</span>

    private void processUploadedFile(FileItem item) { </p>

</span>

        String name = item.getFieldName(); </p>

</span>

</p>

 

</span>

        // 首先尝试获取原来的值 </p>

</span>

        Object oldValue = fileFields.get(name); </p>

</span>

</p>

 

</span>

        if(oldValue == null) { </p>

</span>

           fileFields.put(name, item); </p>

</span>

       } else { </p>

</span>

           // 多个值存储为 List </p>

</span>

</p>

 

</span>

           // 原来为单个值则添加现有的值 </p>

</span>

           try { </p>

</span>

              if(oldValue instanceof FileItem) { </p>

</span>

                  FileItem oldString = (FileItem)oldValue; </p>

</span>

    </p>

</span>

                  List list = new ArrayList(); </p>

</span>

                  list.add(oldString); </p>

</span>

                  list.add(item); </p>

</span>

    </p>

</span>

                  fileFields.put(name, list); </p>

</span>

              } </p>

</span>

           } catch (Exception ex) { </p>

</span>

//           ex.printStackTrace(); </p>

</span>

           } </p>

</span>

</p>

 

</span>

            // 原来为多个值则添加现有的值 </p>

</span>

           try { </p>

</span>

              if(oldValue instanceof List) { </p>

</span>

                  List list = (List)oldValue; </p>

</span>

                    list.add(item); </p>

</span>

                    fileFields.put(name, list); </p>

</span>

              } </p>

</span>

           } catch (Exception ex) { </p>

</span>

//           ex.printStackTrace(); </p>

</span>

           } </p>

</span>

       }        </p>

</span>

    } </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 获取上传的文件项目. </p>

</span>

     * @param name String, 文件域名称 </p>

</span>

     * @return FileItem org.apache.commons.fileupload.FileItem 对象 </p>

</span>

     */ </p>

</span>

    public FileItem getFileItem(String name) { </p>

</span>

       if(!isMultipart) return null; </p>

</span>

</p>

 

</span>

       return (FileItem) (fileFields.get(name)); </p>

</span>

    } </p>

</span>

    </p>

</span>

    /** </p>

</span>

     * 获取多个上传的文件项目. </p>

</span>

     * @param name String, 文件域名称 </p>

</span>

     * @return FileItem[] org.apache.commons.fileupload.FileItem[] 对象 </p>

</span>

     */ </p>

</span>

    public FileItem[] getFileItemValues(String name) { </p>

</span>

       if(!isMultipart) return null; </p>

</span>

</p>

 

</span>

       Object value = fileFields.get(name); </p>

</span>

       if(value != null) { </p>

</span>

           if(value instanceof List) { </p>

</span>

              return (FileItem[]) ((List)value).toArray(new FileItem[0]); </p>

</span>

           }  else if(value instanceof FileItem) { </p>

</span>

              return new FileItem[] { (FileItem)value }; </p>

</span>

           } </p>

</span>

       } </p>

</span>

        </p>

</span>

       return null; </p>

</span>

    }   </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 获取表单参数. </p>

</span>

     * @param name String, 表单域名称 </p>

</span>

     * @return String 表单域值 </p>

</span>

     */ </p>

</span>

    public String getParameter(String name) { </p>

</span>

       if(!isMultipart) { </p>

</span>

          return request.getParameter(name); </p>

</span>

       } </p>

</span>

</p>

 

</span>

       Object value = formFields.get(name); </p>

</span>

       if(value != null) { </p>

</span>

           if(value instanceof String) { </p>

</span>

              return (String)value; </p>

</span>

           } </p>

</span>

       } </p>

</span>

        return null; </p>

</span>

    } </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 获取表单域的多个参数值. </p>

</span>

     * 20100414 </p>

</span>

     * @param name String, 表单域名称 </p>

</span>

     * @return String[] 表单域的多个取值 </p>

</span>

     */ </p>

</span>

    public String[] getParameterValues(String name) { </p>

</span>

       if(!isMultipart) { </p>

</span>

          return request.getParameterValues(name); </p>

</span>

       } </p>

</span>

</p>

 

</span>

       Object value = formFields.get(name); </p>

</span>

       if(value != null) { </p>

</span>

           if(value instanceof List) { </p>

</span>

              return (String[]) ((List)value).toArray(new String[0]); </p>

</span>

           } else if(value instanceof String) { </p>

</span>

              return new String[] { (String)value }; </p>

</span>

           } </p>

</span>

       } </p>

</span>

       </p>

</span>

        return null; </p>

</span>

    } </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 返回当前请求是否为多部分上传请求. </p>

</span>

     */ </p>

</span>

    public boolean isMultipart() </p>

</span>

    { </p>

</span>

       return isMultipart; </p>

</span>

    } </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 保存 FileItem 对象到指定的文件. </p>

</span>

     * @param item FileItem, 要保存的上传文件项目 </p>

</span>

     * @param file File, 要保存到的文件对象 </p>

</span>

     * @return boolean 是否保存成功 </p>

</span>

     */ </p>

</span>

    public static boolean saveFileItem(FileItem item, File file) { </p>

</span>

       try { </p>

</span>

         item.write(file); </p>

</span>

         return true; </p>

</span>

       } catch (Exception ex) { </p>

</span>

//       ex.printStackTrace(); </p>

</span>

         System.out.println("saveFileItem error:" + ex); </p>

</span>

       } </p>

</span>

       return false; </p>

</span>

    } </p>

</span>

</p>

 

</span>

    /** </p>

</span>

     * 获取 FileItem 对象的输入流. </p>

</span>

     * @param item FileItem, 要获取输入流的上传文件对象 </p>

</span>

     * @return InputStream 对象的输入流 </p>

</span>

     */ </p>

</span>

 
  
public static InputStream getInputStreamFromFileItem(FileItem item) { </p>

</span>

       try { </p>

</span>

         return item.getInputStream(); </p>

</span>

       } catch (Exception ex) { </p>

</span>

//       ex.printStackTrace(); </p>

</span>

       } </p>

</span>

       return null; </p>

</span>

    } </p>

</span>

} </p>

</span>

转载请注明:WebLogic Android 博客 » 封装了 Jakarta 文件上传功能的一个类[整理]