上传下载的一个工具类
程序员文章站
2022-04-08 14:57:06
...
自己做了一个上传(利用apache-fileupload组件)下载的一个封装、希望对大家有帮组.请看下面例子。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
/**
* @autor MingMing
*/
public class FileHandler {
/**
* 所有上传文件的总长度最大值
*/
private long SUM_MAX_SIZE = 50 * 1024 * 1024;
/**
* 允许上传的文件默认最大值
*/
private long MAX_SIZE = 10 * 1024 * 1024;
/**
* 允许上传的文件类型
*/
private String[] allowedExt = new String[] { "jpg", "jpeg", "gif", "txt",
"doc", "docx", "mp3", "wma", "m4a" };
/**
* 用完item需delete缓存文件
*/
private Map<String,List<FileItem>> files;
private Map<String,List<String>> parameters;
/**
* 设置输出字符集
*/
private String ENCODING = "UTF-8";
/**
* @param SUM_MAX_SIZE 允许所有文件总长度最大值,当赋值0时使用默认,默认值是50M, 为-1时无限制
* @param MAX_SIZE 允许单个上传文件最大长度是,当赋值0时使用默认,默认值10M,为-1时无限制
* @param ENCODING 输出字符集,默认UTF-8
* @param allowedExt 上传文件类型,当没有传送值时则表示任何类型文件都允许
*/
public FileHandler(long SUM_MAX_SIZE,long MAX_SIZE,String ENCODING,String[] allowedExt) {
if (SUM_MAX_SIZE != 0)
this.SUM_MAX_SIZE = SUM_MAX_SIZE;
if (MAX_SIZE != 0)
this.MAX_SIZE = MAX_SIZE;
if (ENCODING != null)
this.ENCODING = ENCODING;
this.allowedExt = allowedExt;
}
public FileHandler() {
}
public FileHandler upload(HttpServletRequest request) throws UploadException {
RequestContext context = new ServletRequestContext(request);
if(!ServletFileUpload.isMultipartContent(context)) {//判断form表单的传输方式是否是多数据类型
throw new UploadException("您所提供表单类型不是多数据类型multipart-formdata");
}
/**
* 实例化一个硬盘文件工厂,用来配置上传组件ServletFileUpload
*/
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
diskFileItemFactory.setSizeThreshold(4096);// 设置上传文件时用于临时存放文件的内存大小,这里是4K.多于的部分将临时存在硬盘
/**
* 采用系统临时文件目录作为上传的临时目录
*/
File tempfile = new File(System.getProperty("java.io.tmpdir"));
diskFileItemFactory.setRepository(tempfile);
/**
* 用以上工厂实例化上传组件 设置最大上传尺寸
*/
ServletFileUpload fileUpload = new ServletFileUpload(
diskFileItemFactory);
/**
* 单个文件最大的大小
*/
fileUpload.setFileSizeMax(MAX_SIZE);//fileSizeMax = -1 没有上限
/**
* 整个request中最大上限值(包含所有表单[文本域、文件域])
*/
fileUpload.setSizeMax(SUM_MAX_SIZE);//sizeMax = -1 没有上限
/**
* 调用FileUpload.settingHeaderEncoding(”UTF-8″),这项设置可以解决路径或者文件名为乱码的问题。
* 设置输出字符集
*/
fileUpload.setHeaderEncoding(ENCODING);
try {
List<FileItem> items = fileUpload.parseRequest(request);
if (items == null || items.size() == 0) {
throw new UploadException("没有上传一个正确文件!");
}
parameters = new HashMap<String, List<String>>();
files = new HashMap<String, List<FileItem>>();
for (FileItem item: items) {
String fieldName = item.getFieldName();//文本框名称 <input name="">
if (item.isFormField()) {//简单文本域
/**
* 在取字段值的时候,用FileItem.getString(”UTF-8″),这项设置可以解决获取的表单字段为乱码的问题。
*/
String value = item.getString(ENCODING);//文本框的值
List<String> values;
if (parameters.get(fieldName) != null) {
values = parameters.get(fieldName);
} else {
values = new ArrayList<String>();
}
values.add(value);
parameters.put(fieldName, values);
}else { //文件域
long fileLength = item.getSize();
if (fileLength == 0) {
throw new UploadException("文件为空或非法文件!");
}
String userPath = item.getName();//完整路径 C:\sdss\ssss\sss.xls
String fileName = userPath.substring(userPath.lastIndexOf("\\") + 1); //文件名 sss.xls
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); //XLS
//检测文件的后缀名合法性
if (! (allowedExt == null || allowedExt.length == 0) ){
boolean extBoo = false;
for (String ext: allowedExt) {
if (ext.toLowerCase().equals(fileExt)) {
extBoo = true;
break;
}
}
if (!extBoo){//不合法
throw new UploadException("请选择正确得文件格式,包含" + Arrays.toString(allowedExt));
}
}
List<FileItem> values;
if (files.get(fieldName) != null) {
values = files.get(fieldName);
} else {
values = new ArrayList<FileItem>();
}
values.add(item);
files.put(item.getFieldName(), values);
}
}
} catch (FileUploadBase.SizeLimitExceededException e) {
throw new UploadException("01-请求数据的size超出了规定的大小",e);
} catch (FileUploadBase.FileSizeLimitExceededException e) {
throw new UploadException("02-请求文件的size超出了规定的大小",e);
} catch (FileUploadBase.IOFileUploadException e) {
throw new UploadException("03-文件传输出现错误,例如磁盘空间不足等");
} catch (FileUploadBase.InvalidContentTypeException e) {
throw new UploadException("04-无效的请求类型,即请求类型enctype != \"multipart/form-data\"");
} catch (FileUploadException e) {
throw new UploadException("00-上传失败,原因不明.",e);
} catch (UnsupportedEncodingException e) {
throw new UploadException("您提供编码不能识别["+ENCODING+"]",e);
}
return this;
}
/**
* 模仿 request.getParameter()
* @param name
* @return
*/
public String getParameter(String name) {
List<String> v = (List<String>) parameters.get(name);
if (v != null && v.size() > 0) {
return v.get(0);
}
return null;
}
/**
* 模仿 request.getParameterNames();
* @return
*/
public Enumeration<String> getParameterNames() {
return Collections.enumeration(parameters.keySet());
}
/**
* 模仿 request.getParameterValues();
* @param name
* @return
*/
public String[] getParameterValues(String name) {
List<String> v = parameters.get(name);
if (v != null && v.size() > 0) {
return (String[]) v.toArray(new String[v.size()]);
}
return null;
}
/**
* 获取文本域的ContentType
* @param fieldName
* @return
*/
public String[] getContentType(String fieldName) {
List<FileItem> items = (List<FileItem>) files.get(fieldName);
if (items == null) {
return null;
}
List<String> contentTypes = new ArrayList<String>(items.size());
for (int i = 0; i < items.size(); i++) {
FileItem fileItem = (FileItem) items.get(i);
contentTypes.add(fileItem.getContentType());
}
return (String[]) contentTypes.toArray(new String[contentTypes.size()]);
}
/**
* 模仿文本域得request.getParameterNames();
* @return
*/
public Enumeration<String> getFileParameterNames() {
return Collections.enumeration(files.keySet());
}
/**
* 根据文本域表单名称获取文件
* @param fieldName
* @return
*/
public File[] getFile(String fieldName) {
List<FileItem> items = (List<FileItem>) files.get(fieldName);
if (items == null) {
return null;
}
List<File> fileList = new ArrayList<File>(items.size());
for (int i = 0; i < items.size(); i++) {
DiskFileItem fileItem = (DiskFileItem) items.get(i);
fileList.add(fileItem.getStoreLocation());
}
return (File[]) fileList.toArray(new File[fileList.size()]);
}
/**
* @param fieldName
* @return
*/
public String[] getFileNames(String fieldName) {
List<FileItem> items = files.get(fieldName);
if (items == null) {
return null;
}
List<String> fileNames = new ArrayList<String>(items.size());
for (int i = 0; i < items.size(); i++) {
DiskFileItem fileItem = (DiskFileItem) items.get(i);
fileNames.add(getCanonicalName(fileItem.getName()));
}
return (String[]) fileNames.toArray(new String[fileNames.size()]);
}
private String getCanonicalName(String filename) {
int forwardSlash = filename.lastIndexOf("/");
int backwardSlash = filename.lastIndexOf("\\");
if (forwardSlash != -1 && forwardSlash > backwardSlash) {
filename = filename.substring(forwardSlash + 1, filename.length());
} else if (backwardSlash != -1 && backwardSlash >= forwardSlash) {
filename = filename.substring(backwardSlash + 1, filename.length());
}
return filename;
}
/**
* 该方法支持支持国际化 但是文件名不能超过17个汉字 而且在IE6下存在bug
*/
public void downloadI18NFile(HttpServletRequest request,HttpServletResponse response,File src,String showFileName) throws Exception {
if (src == null || !src.exists() || src.length() == 0) {
throw new RuntimeException("系统找不到可用资源!");
}
java.io.BufferedInputStream bis = null;
java.io.BufferedOutputStream bos = null;
try {
long fileLength = src.length();
showFileName = URLEncoder.encode(showFileName, "UTF-8");
String mimeType = request.getSession().getServletContext().getMimeType(src.getName());
mimeType = (mimeType != null)?(mimeType):("application/x-msdownload"); //"application/octet-stream"
System.out.println("mimeType=" + mimeType);
response.setContentType(mimeType);
response.setHeader("Content-disposition", "attachment; filename="
+ showFileName);
//response.setHeader("Content-disposition", "filename="
//+ showFileName);//打开
response.setHeader("Content-Length", String.valueOf(fileLength));
bis = new BufferedInputStream(new FileInputStream(src));
bos = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
} catch (Exception e) {
throw new RuntimeException("下载失败",e);
} finally {
try {
if (bis != null) bis.close();
}catch(IOException ex) {
throw new RuntimeException("关闭资源失败",ex);
}finally {
try{
if (bos != null) bos.close();
}catch(IOException ex) {
throw new RuntimeException("关闭资源失败",ex);
}
}
}
}
/**
* 下载文件. 支持中文,文件名长度无限制 不支持国际化
* @param request
* @param response
* @param src
* @param showFileName
* @throws Exception
*/
public void downloadFile(HttpServletRequest request,HttpServletResponse response,File src,String showFileName) {
if (src == null || !src.exists() || src.length() == 0) {
throw new RuntimeException("系统找不到可用资源!");
}
java.io.BufferedInputStream bis = null;
java.io.BufferedOutputStream bos = null;
try {
long fileLength = src.length();
bis = new BufferedInputStream(new FileInputStream(src));
//response.setContentType("text/html;charset=utf-8");
String mimeType = request.getSession().getServletContext().getMimeType(src.getName());
mimeType = (mimeType != null)?(mimeType):("application/x-msdownload"); //"application/octet-stream"
response.setContentType(mimeType);
//response.setContentType("application/x-msdownload;");
response.setHeader("Content-disposition", "attachment; filename="
+ new String(showFileName.getBytes("GBK"), "ISO8859-1"));//打开、保存
//response.setHeader("Content-disposition", "filename="
//+ new String(showFileName.getBytes("GBK"), "ISO8859-1"));//打开
response.setHeader("Content-Length", String.valueOf(fileLength));
bos = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
} catch (Exception e) {
throw new RuntimeException("下载失败",e);
} finally {
try {
if (bis != null) bis.close();
}catch(IOException ex) {
throw new RuntimeException("关闭资源失败",ex);
}finally {
try{
if (bos != null) bos.close();
}catch(IOException ex) {
throw new RuntimeException("关闭资源失败",ex);
}
}
}
}
/**
* @param req the request.
* @return a new request context.
*/
private RequestContext createRequestContext(final HttpServletRequest req) {
return new RequestContext() {
public String getCharacterEncoding() {
return req.getCharacterEncoding();
}
public String getContentType() {
return req.getContentType();
}
public int getContentLength() {
return req.getContentLength();
}
public InputStream getInputStream() throws IOException {
return req.getInputStream();
}
};
}
public Map<String, List<FileItem>> getFiles() {
return files;
}
public void setFiles(Map<String, List<FileItem>> files) {
this.files = files;
}
public Map<String, List<String>> getParameters() {
return parameters;
}
public void setParameters(Map<String, List<String>> parameters) {
this.parameters = parameters;
}
public static class UploadException extends Exception{
private static final long serialVersionUID = -6797554437005471992L;
public UploadException() {
super();
}
public UploadException(String message, Throwable cause) {
super(message, cause);
}
public UploadException(String message) {
super(message);
}
public UploadException(Throwable cause) {
super(cause);
}
}
////////////////////////////////////////////////////FileUtil
public static String byteCountToDisplaySize(long size) {
String displaySize;
if (size / 1073741824L > 0L)
displaySize = String.valueOf(size / 1073741824L) + " GB";
else if (size / 1048576L > 0L)
displaySize = String.valueOf(size / 1048576L) + " MB";
else if (size / 1024L > 0L)
displaySize = String.valueOf(size / 1024L) + " KB";
else {
displaySize = String.valueOf(size) + " bytes";
}
return displaySize;
}
}
上一篇: 利用Enum解决多种登陆方式