在使用java开发文件上传时,网络上有很多不一样的工具。但是每次如果都需要开发一次,对于使用者来说,这个过程是浪费时间的。所以我们有必要选取其中一个适合自己的文件上传组件,然后对其进一步分装,形成自己的开发工具类。下面我针对自己的工程,对fileupload进行了封装。
fileupload是apache的一个组件,要想使用fileupload,需要用到下面两个jar:commons-fileupload-1.3.1.jar,commons-io-1.1.jar(版本不一样,可能相关jar包不一致,大家根据最新来下载即可)。
下载好相关的jar包,使用eclipse新建一个Dynamic Web Project,然后将jar添加到WEB-INF/lib下面。
由于fileupload组件使用非常简单,所以大家可以参考官网的api,这是学习fileupload最后的一种方式。相关链接:fileupload
下面给出我自己的类和代码:
package net.itaem.servlet; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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; /** * 文件上传的基类,该类可以被继承 * 在配置文件,必须要配置相关的上传属性 * 这是一个父类,主要处理文件的保存,但是对于普通的表单域,由子类来实现 * 每个子类必须实现processNormalField(FileItem fileItem)方法 * 这里采用了模板设计模式... * * */ public abstract class FileuploadServletBase extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; //保存文件文件夹 private static String saveDir = null; //缓存大小 private static int tempCachedSize = 20480; //允许上传的文件类型 private static String[] permittedFileType = null; //单个文件的大小 private static int fileSize = 20480; //最大允许上传的表达大小 private static int maxSize = 204800; //保存上传文件的文件夹 private String savePath; //保存上传文件的map private Map<String, String> uploadedMap = new HashMap<String, String>(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @SuppressWarnings("rawtypes") @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置编码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); //创建一个DiskFileItemFactory DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setRepository(new File(savePath)); //配置保存路径 factory.setSizeThreshold(tempCachedSize); //配置缓存大小 //创建一个ServletFileUpload ServletFileUpload upload = new ServletFileUpload(factory); upload.setSizeMax(maxSize); //设置总体表单大小 upload.setFileSizeMax(fileSize); //设置单个文件大小 //处理表单 try { List<FileItem> items = upload.parseRequest(req); Iterator itemsIterator = items.iterator(); while(itemsIterator.hasNext()){ FileItem fileItem = (FileItem)itemsIterator.next(); if(!fileItem.isFormField()){ //文件域 //去掉不支持上传的文件类型 boolean uploadedFlag = false; for(int i=0; i<permittedFileType.length; i++){ if(permittedFileType[i].contains(fileItem.getContentType())){ uploadedFlag = true; break; } } //如果文件允许上传,那么保存文件到指定上传文件夹中 if(uploadedFlag){ String type = fileItem.getName().substring(fileItem.getName().lastIndexOf(".")); File uploadedFile = newFile(type); //save the file fileItem.write(uploadedFile); //put the file name in a map uploadedMap.put(fileItem.getFieldName(), uploadedFile.getCanonicalPath()); } }else{ //普通表单域 processNormalField(fileItem); } } //上传完毕,进行相关的操作,比如关联数据库,或者将上传文件名保存在xml等文件中 finishedProcess(); } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 获得一个随机字符串,作为上传文件的文件名,防止文件被复写了 * @return 返回一个唯一的随机字符串 * */ public String getRandomFileName(){ UUID fileNameUUID = UUID.randomUUID(); return fileNameUUID.toString(); } @Override public void init() throws ServletException { super.init(); } /** * 初始化servlet,读取配置文件的参数 * */ @Override public void init(ServletConfig config) throws ServletException { if(config.getInitParameter("saveDir") == null){ throw new RuntimeException("参数saveDir不能为空"); }else{ saveDir = config.getInitParameter("saveDir").trim(); } if(config.getInitParameter("permittedFileType") == null){ throw new RuntimeException("参数permittedFileType不能为空"); }else{ permittedFileType = config.getInitParameter("permittedFileType").trim().split(","); } if(config.getInitParameter("fileSize") == null){ throw new RuntimeException("参数fileSize不能为空"); }else{ fileSize = Integer.parseInt(config.getInitParameter("fileSize").trim()); } if(config.getInitParameter("maxSize") == null){ throw new RuntimeException("参数maxSize不能为空"); }else{ maxSize = Integer.parseInt(config.getInitParameter("maxSize").trim()); } if(config.getInitParameter("tempCachedSize") == null){ throw new RuntimeException("参数tempCachedSize不能为空"); }else{ tempCachedSize = Integer.parseInt(config.getInitParameter("tempCachedSize").trim()); } //新建文件夹,如果文件夹不存在 saveDir = createSaveDir(config.getServletContext(), saveDir); } /** * 创建文件夹 * @param context 请求上下文 * @param dirName 文件夹名字 * @return 返回文件夹在当前工程中的路径 * */ private String createSaveDir(ServletContext context, String dirName) { String contextPath = context.getRealPath("/"); //获得工程的 savePath = contextPath + dirName; File dir = new File(savePath); if(!dir.exists()){ //如果文件不存在,创建文件夹 dir.mkdir(); return savePath; }else{ if(dir.isDirectory()){ //文件夹存在,并且已经是文件夹了,直接返回 return savePath; }else{ throw new RuntimeException("该文件" + savePath + "已经存在,请重新配置保存上传文件的文件夹名称"); } } } /** * * 这是一个抽象类,由基类实现,这个方法主要用来处理普通的表单 * 使用模板设计模式... * 处理普通的表单域 * @param fileItem 普通表单域 * */ public abstract void processNormalField(FileItem fileItem); /** * @param type 文件类型 * 穿件一个随机文件,文件的后缀有type决定 * @return 随机文件 * */ public File newFile(String type){ return new File(savePath + File.separator + getRandomFileName() + type); } /** * 将所有的文件名作为一个map返回 * key:表单域名 * value:上传文件名 * @return 返回所有上传文件的map * */ public Map<String, String> getUploadedMap(){ return uploadedMap; } /** * 通过表单域找到上传文件之后的文件名 * @param filedName 表单域名 * @return 上传之后的文件名 * */ public String getUploadedName(String fieldName){ if(fieldName == null) return null; return uploadedMap.get(fieldName); } /** * 表单处理完毕,接下来处理相关操作,比如将上传之后的文件名保存到数据库库之类的操作d * 通常情况下都会进行相关关联 * */ public abstract void finishedProcess(); }
下面给出一个简单实现类:
package net.itaem.servlet; import java.util.Map; import org.apache.commons.fileupload.FileItem; /** * 文件上传的一个类 * 这里处理了普通表单域 * * * */ public class GenericFileUploadServlet extends FileuploadServletBase{ /** * */ private static final long serialVersionUID = 155452356367458695L; @Override public void processNormalField(FileItem fileItem) { System.out.println(fileItem.getFieldName() + "--->" + fileItem.getString()); // do something here } /** * 表单处理完毕,接下来处理相关操作,比如将上传之后的文件名保存到数据库库之类的操作d * */ @Override public void finishedProcess() { Map<String, String> uploadedMap = super.getUploadedMap(); //打印出每个表单域对应的上传文件名 for(String fieldName: uploadedMap.keySet()){ System.out.println(fieldName + "--->" + uploadedMap.get(fieldName)); } } }
在实现类GenericFileuploadServlet中,我们可以对普通的表单域进行处理,也可以对上传之后的文件作出想过处理。所以有了这个设计之后,每次我们可以手动在配置servlet中配置:保存文件夹的名字,缓存大小,支持上传的类型,最大支持上传大小,单个文件大小的信息。下面给出我自己的配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name></display-name> <servlet> <servlet-name>fileupload</servlet-name> <servlet-class>net.itaem.servlet.GenericFileUploadServlet</servlet-class> <init-param> <param-name>tempSaveDir</param-name> <param-value>temp_upload</param-value> </init-param> <init-param> <param-name>saveDir</param-name> <param-value>upload</param-value> </init-param> <init-param> <param-name>tempCachedSize</param-name> <param-value>2048000</param-value> </init-param> <init-param> <param-name>permittedFileType</param-name> <param-value>text/html,application/octet-stream,video/mp4</param-value> </init-param> <init-param> <param-name>fileSize</param-name> <param-value>204800000</param-value> </init-param> <init-param> <param-name>maxSize</param-name> <param-value>20480000</param-value> </init-param> <load-on-startup>10</load-on-startup> </servlet> <servlet-mapping> <servlet-name>fileupload</servlet-name> <url-pattern>/fileupload.do</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
上传之后的文件,保存文件时,注意文件名要具备唯一性。这里使用UUID工具类来生成,哈哈,这个类在java.util包中。
原文地址:http://blog.csdn.net/u010469003/article/details/38304311