文件上传小工具

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);
        }
    }

}
原文地址:https://www.cnblogs.com/stefan95/p/7798825.html