对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 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;

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 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();

}

}

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

文件上传之 commons-fileupload(二)的更多相关文章

  1. JSP 文件上传下载系列之二[Commons fileUpload]

    前言 关于JSP 文件上传的基础和原理在系列一中有介绍到. 这里介绍一个很流行的组件commons fileupload,用来加速文件上传的开发. 官方的介绍是:  让添加强壮,高性能的文件到你的se ...

  2. jsp简易文件上传(common.fileupload)

    昨天开始重新架构我的V&View(维视),之前写文章使用的是一个kindediter的插件,挺好用的.最近不知道咋了,出现了些小问题.早在写V&View的时候就想用以下两种方法实现文章 ...

  3. 实现文件上传功能(FileUpload组件)

    文件上传: 项目中经常用到文件上传. 自己实现文件上传,使用文件上传组件fileupload组件 1.指定表单类型为文件上传, enctype=”multipart/form-data” 2.提交方式 ...

  4. .Net 使用文件上传控件FileUpload上传图片

    例1: 来源:http://long546324.iteye.com/blog/349946 Default.aspx文档: <%@ Page Language="C#" A ...

  5. MVC文件上传-使用jQuery.FileUpload和Backload组件实现文件上传

    本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: 处理文件上传的服务端组件Backload 用于处理文件上传的服务端组件 ...

  6. C# 之 FTPserver中文件上传与下载(二)

            通过上一篇博客<C# 之 FTPserver中文件上传与下载(一)>,我们已经创建好了一个FTPserver,而且该server须要username和password的验证 ...

  7. web文件上传的总结(二)改变Apache默认post值来提高文件上传大小

    上传的文件大小大于2MB的解决方法 #默认apache 允许上大小2MB #技术经理-->修改apache默认配置  php.ini (授权) (1)复制 php.ini -> php1. ...

  8. Struts2实现文件上传报错(二)

    1.具体报错如下 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -he ...

  9. 转:在Struts 2中实现文件上传

    (本文转自:http://www.blogjava.net/max/archive/2007/03/21/105124.html) 前一阵子有些朋友在电子邮件中问关于Struts 2实现文件上传的问题 ...

  10. Spring MVC文件上传教程 commons-io/commons-uploadfile

    Spring MVC文件上传教程 commons-io/commons-uploadfile 用到的依赖jar包: commons-fileupload 1.3.1 commons-io 2.4 基于 ...

随机推荐

  1. RenderMonkey 练习 第三天 【OpenGL renderToTexture】

    渲染到纹理: 1. 新建一个OpenGL 空effect; 2. 添加渲染目标纹理, Add Texture-> Add Render Texture 3. 添加一个渲染pass 4. 将pas ...

  2. http://blog.sina.com.cn/s/blog_4a5dbd380101f031.html

    http://blog.sina.com.cn/s/blog_4a5dbd380101f031.html mvn clean install

  3. [python爬虫] Selenium常见元素定位方法和操作的学习介绍(转载)

    转载地址:[python爬虫] Selenium常见元素定位方法和操作的学习介绍 一. 定位元素方法 官网地址:http://selenium-python.readthedocs.org/locat ...

  4. spfile 和用户环境变量 和export

    RAC数据库环境变量设置 [oracle@rac1 ~]$ sqlplus / as sysdba  SQL*Plus: Release 10.2.0.1.0 - Production on Fri ...

  5. bottle+cherrypy快速开发web服务

    我目前用得最顺手的python web框架是bottle,简单方便. bottle有一个开发用的http服务器,效率不高,单线程,阻塞. 所以,得找个别的服务器来部署. 根据bottle官方的文档,发 ...

  6. centos/7/isos/x86_64 下载

    为了节约有限的可用带宽. 不从mirror.centos.org下载iso映像 以下镜子应该可用的ISO映像: http://mirrors.aliyun.com/centos/7/isos/x86_ ...

  7. 跟着辛星一起用CSS美化商品列表

    说实话,近期对CSS的关注还是蛮多的,不为别的,仅仅是由于自己喜欢,感觉写CSS就像画家绘画一样,使用热情和激情去探索,没有了那份功利心,反而感觉是一种享受.特别有成就感,好啦,今天就分享一期自己用C ...

  8. minic 动作句型处理

    #include "lex_define.h" enum keywords_type//代表一些关键字 { loop_for=,//代表for关键字 loop_while,//代表 ...

  9. MySQL数据库如何导入导出

    1 点击任意一个数据库,然后点击导出,导出为SQL格式,其他一切保持默认(不要勾选"添加 DROP TABLE/DROP VIEW") 2 勾选"另存为文件"点 ...

  10. html 里面的 role 属性是什么意思

    role="button" role是什么意思? html 里面的 role 属性是什么意义和用途 使用role属性告诉辅助设备(如屏幕阅读器)这个元素所扮演的角色,属于WAI-A ...