UploadUtils
使用该工具类只需要在上传的Servlet中调用upload方法,传递要上传到的路径和request对象,该工具类返回一个list集合,list集合中是一个一个Map。如果是多值会用&连接,比如[{name=xxx},{hobby=xxx&xxx},{fileName=xxx}…],文件项会保存它的上传名fileName,要插入数据库的名字saveName,存储文件的路径savePath,上传时间time等。在上传的Servlet中遍历取出值就可以做接下来的操作。工具类用到了年月两级目录打散,文件重命名的CommonUtils.uuid()是UUID.randomUUID().toString().replace(“-“, “”).toUpperCase();就不把文件贴出来了,后面是项目中用到该工具类的例子。
package hui.zhang.upload; import hui.zhang.commons.CommonUtils; import java.io.File; import java.text.NumberFormat; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.ProgressListener; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * 上传小工具 * 传递一个要上传到的磁盘路径和HttpServletRequest对象,返回一个list集合 * 集合中存放着map,通过key得到value进行后续操作 * key:fileName、saveName、savePath、time * @author hui.zhang * @date 2017-10-14 上午8:32:18 */ @SuppressWarnings("all") public class UploadUtils { private static final int CACHE = 1024*1024*3; //设置缓存区大小3M private static final int FILEMAX = 1024*1024*100; //设置上传文件最大100M /** * 给本方法传递一个要上传到的路径 如 G://upload * 本方法会返回一个list集合,包含普通文件项的name和value * 复选框多值返回用&拼接 如 hobby=a&b&c * 上传文件项在集合中有上传文件名fileName,存储文件名saveName * 存储路径savePath和上传时间time * @param path * @param request * @return * @throws Exception */ public static List upload(String path, final HttpServletRequest request) throws Exception { //创建工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //设置缓冲区大小,默认10K factory.setSizeThreshold(CACHE); //通过工厂得到核心解析器 ServletFileUpload sfu = new ServletFileUpload(factory); //设置文件上传最大限制 sfu.setSizeMax(FILEMAX); //处理上传文件中文乱码 sfu.setHeaderEncoding("UTF-8"); /** * 设置上传进度,存到session域中 * 可以通过异步请求从session中实时取出上传进度 */ sfu.setProgressListener(new ProgressListener() { //参数1:已上传文件大小 //参数2:文件总大小 @Override public void update(long pBytesRead, long pContentLength, int pItems) { double progress= Double.parseDouble(pBytesRead+"")/Double.parseDouble(pContentLength+""); //获取百分比格式化对象 NumberFormat format = NumberFormat.getPercentInstance(); //保留两位小数 format.setMinimumFractionDigits(2); String progress_str = format.format(progress); //保存在session域中,匿名内部类 需要将request用final修饰】 request.getSession().setAttribute("progress", progress_str); } }); //解析请求,得到FileItem对象 List<FileItem> list = sfu.parseRequest(request); //创建一个list集合,将普通文件项和上传文件项的信息封装之,返回 List<Map> l = new LinkedList(); //创建一个map,把每个文件项信息映射一份,可以修改复选框一对多单独存储问题 Map m = new LinkedHashMap<>(); //定义要返回的list结合的索引 int i = -1; for (FileItem fileItem : list) { //创建局部map,封装每个文件项,最后添加到集合中 Map map = new HashMap(); if (fileItem.isFormField()) { //得到普通文件项名称 String fieldName = fileItem.getFieldName(); //值 String value = fileItem.getString("UTF-8"); //如果是空不添加 if (value.equals("") || value == null || value.trim().isEmpty()) { continue; } //从映射map中取出相同文件项名称 例如 复选框又有相同的名称 hobby if (m.containsKey(fieldName)) { //让list集合移除掉刚才添加的 l.remove(i); //hobby=a&b 覆盖之 map.put(fieldName, m.get(fieldName)+"&"+value); m = map; //映射 } else { i++; //索引加1 map.put(fieldName, value); //把控件名和值添加到局部map hobby=a m = map; //映射 } } else { if (fileItem.getSize() > FILEMAX) { System.out.println("文件大于设定的100M了!"); request.getSession().setAttribute("info", "文件过大,不能大于100M!"); } String filename = fileItem.getName(); // a.jpg if (filename.equals("") || filename.trim().isEmpty() || filename == null) { continue; } String dir = MakeDir.getDir(); // "/2017/10/" // G://upload + /2017/10/ String root = path + dir; File file = new File(path, dir); if (!file.exists()) { file.mkdirs(); } // xxxxxxxxx_a.jpg String savename = CommonUtils.uuid()+"_"+filename; // G://upload/2017/10/xxxxxxxx_a.jpg File savepath = new File(file, savename); fileItem.write(savepath); fileItem.delete(); map.put("fileName", filename); map.put("saveName", savename); map.put("savePath", root+savename); map.put("time", new Date()); } l.add(map); } return l; } }
MakeDir
package hui.zhang.upload; import java.util.Calendar; /** * 返回当前的年月组成二级目录 * @return "/2017/10/" * @author hui.zhang * @date 2017-10-14 上午8:46:39 */ @SuppressWarnings("all") public class MakeDir { public static String getDir() { Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); int month = calendar.get(calendar.MONTH)+1; return "/"+year+"/"+month+"/"; } }
举个栗子
public class AdminProductUploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { List<Map> list = UploadUtils.upload("D:/tomcat/apache-tomcat-7.0.81/webapps/day08_store/products", request); System.out.println(list); Product product = new Product(); product.setPid(CommonUtils.uuid()); product.setPdate(new Date()); product.setPflag(0); for (Map<String,String> map : list) { BeanUtils.populate(product, map); Set<String> set = map.keySet(); for (String key : set) { if ("savePath".equalsIgnoreCase(key)) { String path = map.get(key); String[] split = path.split("day08_store/"); product.setPimage(split[1]); } else if("cid".equals(key)) { ProductService productService = (ProductService) BeanFactory.getBean("productService"); Category category = productService.findCategory(map.get(key)); product.setCategory(category); } } } AdminProductDao adminProductDao = new AdminProductDao(); System.out.println(product.toString()); adminProductDao.add(product); response.sendRedirect(request.getContextPath()+"/AdminProductServlet?method=findAllByPage&currPage=1"); } catch (Exception e) { throw new RuntimeException(e); } } }