就在前段时间,还在苦于找到不到合适的上传组件,虽然很早就知道了 common-fileupload,但当时却因为没有找到如何获取表单参数的方法而使用 jspSmartUpload,历尽艰辛终于找到了它的 jar,可是使用后才发现此东西对中文参数支持奇差,甚至需要修改源代码才能解决问题,可是jspSmartUpload并不是开源的项目,而且开发团队也不再对它进行更新,连官方网站都关门大吉了,情急之下使用JadClipse 反编译了它的jar包,原以为问题算是得到解决了,谁知道后来却发现获取到的参数经常出现部分中文乱码,而且还不是固定的汉字出现乱码,仔细研究加Google后才找出了规律,原来是奇数字数的中文会出现乱码,而偶数字数的则正常,阅读了源代码,终于还是没耐心阅读下去,而且看到网上还有评论说该组件有内存泄露的问题,于是才下定决定搞定common-fileupload。
于是从 http://jakarta.apache.org/commons/fileupload/ 下载到了最新版的 FileUpload 1.2,阅读了部分文档跟例子,终于找到了获取表单中参数的方法并对该组件做了进一点封装,使其更容易使用,并支持单文件上传和多文件上传两种方式,首先定义一个基类放置公共属性:
FileUploadBase.java
import java.io.File;
import java.util.HashMap;
import java.util.Map;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
publicabstractclass FileUploadBase
{
protected Map<String, String> parameters =new HashMap<String, String>();// 保存普通form表单域
protected String encoding ="utf-8"; // 字符编码,当读取上传表单的各部分时会用到该encoding
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected UploadFileFilter filter =null; // 文件过滤器, 默认为NULL 不过滤
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* The directory in which uploaded files will be stored, if stored on disk.
*/
protectedint sizeThreshold = DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
*
* The maximum size permitted for the complete request, as opposed to
*
* {@link #fileSizeMax}. A value of -1 indicates no maximum.
*
*/
protectedlong sizeMax =-1;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* The directory in which uploaded files will be stored, if stored on disk.
*/
protected File repository;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public String getParameter(String key)
{
return parameters.get(key);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public String getEncoding()
{
return encoding;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicvoid setEncoding(String encoding)
{
this.encoding = encoding;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 获取上传文件最大的大小,单位为Byte(字节),为-1时表示无限制
* @return
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publiclong getSizeMax()
{
return sizeMax;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 设置上传文件最大的大小,单位为Byte(字节),为-1时表示无限制
* @param sizeMax
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicvoid setSizeMax(long sizeMax)
{
this.sizeMax = sizeMax;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicint getSizeThreshold()
{
return sizeThreshold;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicvoid setSizeThreshold(int sizeThreshold)
{
this.sizeThreshold = sizeThreshold;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* Returns the directory used to temporarily store files that are larger
* than the configured size threshold.
*
* @return The directory in which temporary files will be located.
*
* @see #setRepository(java.io.File)
*
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public File getRepository()
{
return repository;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* Sets the directory used to temporarily store files that are larger than
* the configured size threshold.
*
* @param repository
* The directory in which temporary files will be located.
*
* @see #getRepository()
*
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicvoid setRepository(File repository)
{
this.repository = repository;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 获取参数列表
* @return
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Map<String, String> getParameters()
{
return parameters;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 获取过滤器
* @return
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public UploadFileFilter getFilter()
{
return filter;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 设置文件过滤器,不符合过滤器规则的将不被上传
* @param filter
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicvoid setFilter(UploadFileFilter filter)
{
this.filter = filter;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 验证文件是否有效
* @param item
* @return
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
protectedboolean isValidFile(FileItem item)
{
return item ==null|| item.getName() ==""|| item.getSize() ==0|| (filter !=null&&!filter.accept(item.getName())) ?false : true;
}
}
支持单文件上传的 SingleFileUpload 类:
SingleFileUpload.java
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.List;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
import javax.servlet.http.HttpServletRequest;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
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;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
publicclass SingleFileUpload extends FileUploadBase
{
private FileItem fileItem;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
*
* @param request
* @throws UnsupportedEncodingException
*/
publicvoid parseRequest(HttpServletRequest request)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
throws UnsupportedEncodingException
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DiskFileItemFactory factory =new DiskFileItemFactory();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
factory.setSizeThreshold(sizeThreshold);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (repository !=null)
factory.setRepository(repository);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ServletFileUpload upload =new ServletFileUpload(factory);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
upload.setHeaderEncoding(encoding);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
List<FileItem> items = upload.parseRequest(request);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (FileItem item : items)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (item.isFormField())
{
String fieldName = item.getFieldName();
String value = item.getString(encoding);
parameters.put(fieldName, value);
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
}else
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (!super.isValidFile(item))
{
continue;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (fileItem ==null)
fileItem = item;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
}catch (FileUploadException e)
{
e.printStackTrace();
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 上传文件, 调用该方法之前必须先调用 parseRequest(HttpServletRequest request)
* @param fileName 完整文件路径
* @throws Exception
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicvoid upload(String fileName) throws Exception
{
File file =new File(fileName);
uploadFile(file);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 上传文件, 调用该方法之前必须先调用 parseRequest(HttpServletRequest request)
* @param parent 存储的目录
* @throws Exception
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicvoid upload(File parent) throws Exception
{
if (fileItem ==null)
return;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
String name = fileItem.getName();
File file =new File(parent, name);
uploadFile(file);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
privatevoid uploadFile(File file) throws Exception
{
if (fileItem ==null)
return;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
long fileSize = fileItem.getSize();
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (sizeMax >-1&& fileSize >super.sizeMax)
{
String message = String.format("the request was rejected because its size (%1$s) exceeds the configured maximum (%2$s)", fileSize, super.sizeMax);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
thrownew org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException(message, fileSize, super.sizeMax);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
String name = fileItem.getName();
fileItem.write(file);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 获取文件信息
* 必须先调用 parseRequest(HttpServletRequest request)
* @return
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public FileItem getFileItem()
{
return fileItem;
}
}
支持多文件上传的 MutiFileUpload 类:
MutiFileUpload.java
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
import javax.servlet.http.HttpServletRequest;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
publicclass MutiFileUpload extends FileUploadBase
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private Map<String, FileItem> files;// 保存上传的文件
privatelong filesSize =0; // 所有文件的总大小
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
publicvoid parseRequest(HttpServletRequest request)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
throws UnsupportedEncodingException
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
files =new HashMap<String, FileItem>();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Create a factory for disk-based file items
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DiskFileItemFactory factory =new DiskFileItemFactory();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
factory.setSizeThreshold(sizeThreshold);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (repository !=null)
factory.setRepository(repository);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ServletFileUpload upload =new ServletFileUpload(factory);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
upload.setHeaderEncoding(encoding);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
List<FileItem> items = upload.parseRequest(request);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (FileItem item : items)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (item.isFormField())
{
String fieldName = item.getFieldName();
String value = item.getString(encoding);
parameters.put(fieldName, value);
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
}else
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (super.isValidFile(item))
{
continue;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
String fieldName = item.getFieldName();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
files.put(fieldName, item);
filesSize += item.getSize();
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
}catch (FileUploadException e)
{
e.printStackTrace();
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 上传文件, 调用该方法之前必须先调用 parseRequest(HttpServletRequest request)
* @param parent 文件存储的目录
* @throws Exception
*/
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
publicvoid upload(File parent) throws Exception
{
if (files.isEmpty())
return;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (sizeMax >-1&& filesSize >super.sizeMax)
{
String message = String.format("the request was rejected because its size (%1$s) exceeds the configured maximum (%2$s)", filesSize, super.sizeMax);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
thrownew SizeLimitExceededException(message, filesSize, super.sizeMax);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (String key : files.keySet())
{
FileItem item = files.get(key);
String name = item.getName();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
File file =new File(parent, name);
item.write(file);
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Map<String, FileItem> getFiles()
{
return files;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
当然还少不了过滤器 UploadFileFilter:
UploadFileFilter.java
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
publicinterface UploadFileFilter
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/** *//**
* 通过文件名后缀判断文件是否被接受
* @param filename 文件名,不包括路径
* @return
*/
publicboolean accept(String filename);
}
这样在 Servlet 中我们就可以通过简单的代码实现文件的上传了:
SingleFileUpload upload =new SingleFileUpload();
upload.parseRequest(request);
File parent =new File("C:\\upload\\");
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
try
{
upload.upload(parent);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
catch(org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException e)
{
// 文件大小超出最大值
e.printStackTrace();
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
}catch (Exception e)
{
e.printStackTrace();
}
相比 jspSmartUpload 我觉得 common-fileupload 有如下的优点:
1、开源;
2、Jakarta项目组的支持,开发十分活跃,而 jspSmartUpload 则已经停止开发了;
3、不需要写入文件之前即可获取到参数和文件信息,jspSmartUpload 则需要在获取之前调用 upload 方法;
4、对中文支持友好。
转自:http://www.cnblogs.com/yyw84/archive/2007/06/27/797652.html