`
lhxctc
  • 浏览: 53050 次
  • 性别: Icon_minigender_1
  • 来自: 江西
社区版块
存档分类
最新评论

上传下载的一个工具类

    博客分类:
  • Java
阅读更多

自己做了一个上传(利用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;
	}
	
}
 
分享到:
评论

相关推荐

    上传下载工具类java

    `上传工具类使用说明.docx`文件应该是对`UploadUtils.java`类的详细使用指南,包括如何初始化、调用上传和下载方法、配置服务器地址、处理可能出现的问题等。这份文档对于开发者来说是非常宝贵的,可以快速理解并...

    java文件上传下载工具类

    以下是对"java文件上传下载工具类"这一主题的详细解释。 首先,让我们了解文件上传。在Web应用中,用户可能需要上传文件,如图片、文档或视频。Java通过Servlet API提供了处理文件上传的功能。Servlet 3.0及以上...

    java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类

    java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件...

    图片的上传下载及工具类

    本文将详细讲解如何实现图片的上传与下载,并介绍一个实用的工具类`UpOrDownLoadUtil.java`。 首先,我们来探讨图片上传的过程。在Web应用中,通常用户通过表单提交图片文件到服务器。这个过程涉及到前端和后端两个...

    JAVA 操作FTP的工具类,上传,下载,删除功能都有了。

    在这个场景中,我们有一个工具类,它包含了FTP的上传、下载和删除功能,这对于任何需要与FTP服务器交互的应用程序都是非常有用的。 首先,让我们详细了解一下FTP上传功能。在Java中,我们可以使用`FTPClient`类来...

    java 文件上传工具类 java 文件上传工具类

    java 文件上传工具类 java 文件上传工具类java 文件上传工具类 java 文件上传工具类java 文件上传工具类 java 文件上传工具类java 文件上传工具类 java 文件上传工具类java 文件上传工具类 java 文件上传工具类java ...

    ftp上传下载工具类

    FTP上传下载工具类通常是指一个编程接口或代码库,为开发者提供便捷的FTP客户端功能,包括连接到FTP服务器、上传文件、下载文件以及管理远程目录等操作。 在开发中,我们可能遇到以下关键知识点: 1. FTP基本概念...

    上传下载工具类

    上传下载工具类, FileDownLoad.java

    java版ftp上传下载工具类

    Java FTP上传下载工具类是基于Apache的Commons Net库实现的,这个库为Java开发者提供了FTP(文件传输协议)客户端功能。Apache Commons Net是Apache软件基金会的一个项目,它提供了多种Internet协议的Java实现,包括...

    安卓文件下载上传解压相关-工具类支持多线程断点下载.rar

    这个压缩包"安卓文件下载上传解压相关-工具类支持多线程断点下载.rar"包含了一个工具类,旨在帮助开发者处理这些操作。下面将详细讨论相关知识点。 1. 多线程下载: 在Android中,为了提高文件下载速度,通常会采用...

    MinIO通用上传工具类

    MinIO通用上传工具类

    上传文件工具类

    此外,为了优化性能,文件上传工具类可能使用了多线程或者异步处理。Java的并发API,如`ExecutorService`、`Future`和`Callable`,可以帮助我们有效地管理这些任务。同时,工具类也可能实现了进度更新接口,以便在上...

    文件上传工具类

    java io 文件上传工具类

    PHP上传视频文件图片工具类

    在创建一个上传工具类时,首先需要确保表单正确设置了`enctype="multipart/form-data"`,这是上传文件所必需的。然后,我们需要在服务器端处理`$_FILES`数组,检查文件是否上传成功,是否有错误,以及文件的大小和...

    ftp上传下载文件工具类

    项目中添加该工具类,用一下语句调用 FTPUtil ftpUtil = new FTPUtil("172.16.1.41",21,"admin","123456"); ftpUtil.downLoadFile&#40;"20190913.txt","D:\\ftplocal\\20190913.txt"&#41;; ftpUtil.uploadFile&#...

    Java使用NFS实现上传、下载、读取文件工具类

    封装性:工具类封装了NFS相关的复杂连接、认证和I/O操作细节,使得业务层代码无需关心底层通信协议,只需通过简单API即可操作远程文件。 可配置性:允许灵活配置NFS服务器地址、挂载点以及其他相关参数,使工具类...

    java servlet上传下载工具类

    总结,"java servlet上传下载工具类"是Java Web开发中一个实用的组件,它封装了复杂的文件操作逻辑,使开发者能更高效、安全地处理文件上传和下载任务。这个工具类基于"孤傲苍狼"的实现,具有较高的稳定性和灵活性,...

    文件上传下载工具类

    主要用于图片的上传和下载,也可以用于文件的上传和下载

    文件上传下载工具类单个文件上传多种形式下载文件

    文件上传下载工具类单个文件上传,多种传参形式下载文件

Global site tag (gtag.js) - Google Analytics