ParameterUtil.java 文件传输工具类

package com.util.common;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

public class ParameterUtil {
    //默认参数配置
    public static final Long MAX_SIZE = 10000000L;           //上传的最大长度位3M
    public static final Long FILE_MAX_SIZE = 3000000L;      //上传单个文件的最大值
    //进行存储目录的设置时,必须以 / 作为完结,否则会报错
    public static final String TEMP_DIR = "/temp/";         //临时保存目录
    public static final String UPLOAD_DIR = "/upload/";     //目标存储路径
    public static final String DEFAULT_ENCODING = "UTF-8";  //文件编码

    //这个程序类是一个与JavaWeb开发密切耦合的工具类,必须运行在WEB容器内
    private HttpServletRequest request;     //实现请求的接收
    private String uploadFile;          //【属性】白村上传路径
    private String tempFile;            //【属性】保存临时存储路径
    private String encoding;            //【属性】保存编码设置
    private long maxSize;               //【属性】上传文件的最大长度
    private long fileMaxSize;           //【属性】保存每个上传文件的最大长度

    //考虑提交的表单是否经过封装,即enctype="multipart/form-data":
    private boolean uploadFlag;         //封装的处理标记
    private ServletFileUpload fileUpload;//实现文件上传的处理
    //获取所有存储的临时文件名称的集合
    //可用于上传之后临时目录的清空处理
    private List<String> tempFileNames = new ArrayList<>();
    //所有请求处理时候,FileUpload组件是需要循环进行的,而这个类就是减少这样的循环
    //在一次循环就保存所有请求的参数 和 参数值的数组(因为有的参数值可能是一个还可能是一组)
    //若存的是文件,则保存的是临时文件的名称
    private Map<String, String[]> paramMap = new HashMap<>();

    //构造方法一:
    public ParameterUtil(HttpServletRequest request) {
        this(request, UPLOAD_DIR, TEMP_DIR, DEFAULT_ENCODING, MAX_SIZE, FILE_MAX_SIZE);
    }

    //构造方法二:
    public ParameterUtil(HttpServletRequest request, String uploadFile) {
        this(request, uploadFile, TEMP_DIR, DEFAULT_ENCODING, MAX_SIZE, FILE_MAX_SIZE);
    }

    //构造方法三:
    public ParameterUtil(HttpServletRequest request, String uploadFile, String tempFile, String encoding, long maxSize, long fileMaxSize) {
        this.request = request;
        //进行存储目录的设置时,必须以 / 作为完结,否则会报错
        if (uploadFile.endsWith("/")) {

            this.uploadFile = uploadFile;
        } else {
            this.uploadFile = uploadFile + "/";
        }
        if (uploadFile.endsWith("/")) {
            this.tempFile = tempFile;
        } else {
            this.tempFile = tempFile + "/";
        }
        this.encoding = encoding;
        this.maxSize = maxSize;
        this.fileMaxSize = fileMaxSize;
        this.handleParameter();     //在构造的时候就实现对请求参数的处理

    }

    private void handleParameter() {         //对请求参数进行处理
        //针对提交的表单是否封装,请求参数的获取机制也是不同的
        if (this.uploadFlag = this.request.getContentType() != null &&
                this.request.getContentType().startsWith("multipart/form-data")) {
            //证明表单已进行过封装操作,需要用FileUpload组件进行处理
            DiskFileItemFactory factory = new DiskFileItemFactory();    //磁盘管理类
            factory.setRepository(new File(this.tempFile));            //设置临时存储文件夹
            this.fileUpload = new ServletFileUpload(factory);//上传处理的核心类
            fileUpload.setSizeMax(this.maxSize);                        //上传的最大容量
            fileUpload.setFileSizeMax(this.fileMaxSize);                //单个文件上传的最大容量

            if (fileUpload.isMultipartContent(request)) {             //若当前存在文件正在上传
                try {
                    //对当前请求进行参数的分析,所得的内容都保存在了Map里面
                    //String 是参数名称; List 是参数内容
                    Map<String, List<FileItem>> map = this.fileUpload.parseParameterMap(request);
                    //有了参数和参数的内容,开整
                    for (Map.Entry<String, List<FileItem>> entry : map.entrySet()) {
                        //对Map进行迭代
                        String paramName = entry.getKey();          //获取提交的参数名称
                        List<FileItem> allItems = entry.getValue(); //获取提交的参数内容
                        //如果发现提交的是普通的文本数据,则直接保存至paramMap中
                        //如果发现提交的是上传文件,则生成一个新的文件名称,保存的是文件名称
                        String[] values = new String[allItems.size()];  //根据提交的参数内容个数决定字符串数组的大小
                        int foot = 0;   //实现字符串数组的索引控制
                        for (FileItem item : allItems) {      //循环参数的内容
                            if (item.isFormField()) {         //如果内容是一个普通的文本参数
                                String value = item.getString(this.encoding);
                                values[foot++] = value;       //文本文件保存的是参数内容
                            } else {      //内容是一个二进制的文件
                                //需要对临时存储的文件创建新的文件名称,并将文件保存在临时文件夹之中
                                String fileName = this.saveTempFile(item);  //保存临时文件
                                //private List<String> tempFileNames = new ArrayList<>();
                                this.tempFileNames.add(fileName);           //保存临时文件名称
                                values[foot++] = fileName;                  //二进制文件保存的是临时文件名称
                            }
                        }
                        // 最终能够实现数据信息查询的是ParamMap集合,将所有的数据保存在ParamMap集合内
                        // private Map<String, String[]> paramMap = new HashMap<>();
                        this.paramMap.put(paramName, values);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //因为最终生成的随机文件名称需要原始文件名称的后缀,所以可通过 FileItem 可以获取原始文件的后缀及MIME类型
    public String saveTempFile(FileItem item) throws Exception {
        if (item.getSize() > 0) { //有上传文件存在
            String fileName = "temp." + this.getUUIDName(item);  //临时存储文件名称前加上 temp
            String filePath = this.request.getServletContext()
                    .getRealPath(this.tempFile) + fileName; //临时存储路径
            item.write(new File(filePath)); //实现文件保存
            item.delete();  //删除FileItem里存储的文件,存储在temp文件夹中的并未删除
            return fileName;
        }
        return null;
    }

    //实现存储文件名称的随机创建
    public String getUUIDName(FileItem item) {
        //这段copy即可
        return UUID.randomUUID() + "." + item.getContentType()
                .substring(item.getContentType().lastIndexOf("/") + 1);
    }

    //处理方法一:根据参数名称获取单个参数的内容(或首个内容)
    public String getParameterValue(String paramName) {
        if (this.uploadFlag) {        //表单已封装
            if (this.paramMap.containsKey(paramName)) {   //当前的参数内容存在
                return this.paramMap.get(paramName)[0]; //返回参数的第一个内容
            }
            return null;    //参数内容不存在则返回null
        }
        return this.request.getParameter(paramName);    //表单未封装,则直接HttpServletRequest方法处理
    }

    //处理方法二:根据参数名称获取单个参数的内容数组(返回的是数组)
    public String[] getParameterValues(String paramName) {
        if (this.uploadFlag) {        //表单已封装
            if (this.paramMap.containsKey(paramName)) {   //当前的参数内容存在
                return this.paramMap.get(paramName);    //返回参数的内容数组
            }
            return null;    //参数内容不存在则返回null
        }
        return this.request.getParameterValues(paramName);//表单未封装,则直接HttpServletRequest方法处理
    }

    //处理方法三:获取全部参数名称
    public Set<String> getParameterNames() {
        if (this.uploadFlag) {        //表单已封装
            return this.paramMap.keySet();      //获得封装后所有参数的名称
        }
        return this.request.getParameterMap().keySet(); //表单未封装,则直接HttpServletRequest方法处理
    }

    //处理方法四:最终能够实现数据信息查询的是ParamMap集合,获取保存所有数据的ParamMap集合
    public Map<String, String[]> getParameterMap() {
        if (this.uploadFlag) {        //表单已封装
            return this.paramMap;
        }
        return this.request.getParameterMap();
    }

    //所有的文件在进行处理之后全部都已经保存在了 temp 目录中,但最终需要存储在 upload 目录中

    //处理方法五:获取指定参数的临时存储文件的名称(有temp前缀),同时生成并返回 upload 的保存名称
    public List<String> getUUIDName(String paramName) throws Exception {
        List<String> uuidNames = new ArrayList<>();     //保存最终生成的upload文件名称
        String[] fileNames = this.paramMap.get(paramName);//获取临时文件的名称集合
        for (String fileName : fileNames) {
            if(fileName == null){//如果没有参数传递
                return null;
            }
            uuidNames.add("upload." + UUID.randomUUID() + "." +
                    fileName.substring(fileName.lastIndexOf(".") + 1));
        }
        return uuidNames;   //返回upload存储的文件名称集合
    }

    //处理方法六:temp文件夹 转保存到 upload文件夹,文件名称未getUUIDName()方法生成的
    public void saveUploadFile(String paramName, List<String> uploadFileNames) throws Exception {
        String[] fileNames = this.paramMap.get(paramName);  //获取临时文件名称
        for (int x = 0; x < fileNames.length; x++) {
            File srcFile = new File(this.request
                    .getServletContext().getRealPath(this.tempFile) + fileNames[x]);
            File dstFile = new File(this.request.
                    getServletContext().getRealPath(this.uploadFile) + uploadFileNames.get(x));
            InputStream input = new FileInputStream(srcFile);   //临时文件输入流
            OutputStream output = new FileOutputStream(dstFile);//临时文件输出流
            input.transferTo(output);   //文件转存
            input.close();
            output.close();
        }
    }

    //处理方法七:清除temp目录下的内容
    public void clean(){
        //private List<String> tempFileNames = new ArrayList<>();
        if(this.tempFileNames != null && this.tempFileNames.size() > 0){
            for(String fileName : this.tempFileNames){
                String filePath = this.request.getServletContext()
                        .getRealPath(this.tempFile) + fileName;
                File file = new File(filePath);
                if(file.exists()){
                    file.delete();
                }
            }
        }
    }

    //处理方法八:获取临时目录 temp文件夹 下的所有文件名称
    public List<String> getTempFileNames(){
        return tempFileNames;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值