All Downloads are FREE. Search and download functionalities are using the official Maven repository.

matrix.boot.common.utils.http.UploadUtil Maven / Gradle / Ivy

There is a newer version: 2.1.11
Show newest version
package matrix.boot.common.utils.http;

import lombok.extern.slf4j.Slf4j;
import matrix.boot.common.dto.UploadProgressDto;
import matrix.boot.common.dto.UploadResultDto;
import matrix.boot.common.exception.ServiceException;
import matrix.boot.common.utils.*;
import org.apache.commons.collections4.CollectionUtils;
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;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * 上传工具
 *
 * @author wangcheng
 */
@Slf4j
public class UploadUtil {

    /**
     * 文件上传标识
     */
    private static final String MULTIPART_FLAG = "multipart";

    /**
     * 文件路径,后缀名过滤器(分割符|)
     */
    private String filePath, suffixFilter;

    /**
     * 文件最大大小(B)
     */
    private Long fileMaxSize;

    /**
     * 上传servlet
     */
    private ServletFileUpload servletFileUpload;

    private UploadUtil() {
    }

    private UploadUtil(String filePath, Long fileMaxSize, String suffixFilter) {
        AssertUtil.notNullTip(filePath, "filePath");
        AssertUtil.notNullTip(suffixFilter, "suffixFilter");
        this.filePath = filePath;
        this.fileMaxSize = fileMaxSize;
        this.suffixFilter = suffixFilter;
        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
        servletFileUpload = new ServletFileUpload(diskFileItemFactory);
        servletFileUpload.setSizeMax(fileMaxSize);
        File cacheDir = new File(filePath + "/cache");
        FileUtil.mkdirs(cacheDir.getAbsolutePath());
        diskFileItemFactory.setRepository(cacheDir);
        diskFileItemFactory.setSizeThreshold(1024 * 2048);
    }

    /**
     * 获取实例
     *
     * @param filePath     文件路径
     * @param fileMaxSize  文件大小(B)
     * @param suffixFilter 文件后缀过滤
     * @return 上传工具
     */
    public static UploadUtil getInstance(String filePath, Long fileMaxSize, String suffixFilter) {
        return new UploadUtil(filePath, fileMaxSize, suffixFilter);
    }

    /**
     * 文件上传
     *
     * @return 上传结果
     */
    public Map upload(HttpServletRequest request) {
        return upload(request, null);
    }

    /**
     * 文件上传
     *
     * @return 上传结果
     */
    public Map upload(HttpServletRequest request, UploadProgressDto progress) {
        if (!request.getClass().getName().toLowerCase().contains(MULTIPART_FLAG)) {
            return uploadNoMultipart(request, progress);
        } else {
            return uploadMultipart(request);
        }
    }

    /**
     * multipart开启后进入
     * spring.servlet.multipart.enabled=true
     *
     * @param request 请求
     * @return 上传结果
     */
    private Map uploadMultipart(HttpServletRequest request) {
        try {
            Collection parts = request.getParts();
            if (parts != null) {

                return upload(parts);
            }
        } catch (Exception e) {
            throw new ServiceException(e);
        }
        return null;
    }

    /**
     * multipart关闭后进入
     * spring.servlet.multipart.enabled=false
     *
     * @param request  请求体
     * @param progress 进度条
     * @return 上传结果
     */
    private Map uploadNoMultipart(HttpServletRequest request, UploadProgressDto progress) {
        if (!ServletFileUpload.isMultipartContent(request)) {
            log.error("ContentType不存在(multipart/form-data)上传失败");
            return null;
        }
        if (progress != null) {
            servletFileUpload.setProgressListener(progress);
        }
        List list;
        try {
            list = servletFileUpload.parseRequest(request);
        } catch (FileUploadException e) {
            throw new ServiceException(e);
        }
        return upload(list);
    }

    /**
     * 上传数据
     *
     * @param list 列表
     * @return 上传结果
     */
    private Map upload(Collection list) {
        Map result = new HashMap<>(list.size());
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        CountDownLatch countDownLatch = new CountDownLatch(list.size());
        for (Object item : list) {
            //字段名
            String fieldName;
            //文件名
            String fileName;
            //文件大小
            long fileSize;
            if (item instanceof FileItem) {
                if (((FileItem) item).isFormField()) {
                    countDownLatch.countDown();
                    continue;
                }
                fieldName = ((FileItem) item).getFieldName();
                fileName = ((FileItem) item).getName();
                fileSize = ((FileItem) item).getSize();
            } else if (item instanceof Part) {
                if (((Part) item).getContentType() == null) {
                    countDownLatch.countDown();
                    continue;
                }
                fieldName = ((Part) item).getName();
                fileName = ((Part) item).getHeader("content-disposition").split("filename=\"")[1].replaceAll("\"", "");
                fileSize = ((Part) item).getSize();
            } else {
                countDownLatch.countDown();
                continue;
            }
            //后缀名
            String suffixName = FileUtil.getSuffix(fileName);
            //系统文件名
            String sysFileName = RandomUtil.getUUID() + suffixName;
            //结果子类
            UploadResultDto resultItem = new UploadResultDto(fieldName, fileName, sysFileName);
            //校验数据
            if (fileSize <= 0) {
                resultItem.setMessage("文件大小为0B");
                result.put(fieldName, resultItem);
                countDownLatch.countDown();
                continue;
            }
            if (fileSize > this.fileMaxSize) {
                resultItem.setMessage("文件大于" + this.fileMaxSize + "B");
                result.put(fieldName, resultItem);
                countDownLatch.countDown();
                continue;
            }
            if (!"*".equals(this.suffixFilter) && !this.suffixFilter.contains(suffixName)) {
                resultItem.setMessage("文件类型不在" + this.suffixFilter + "范围内");
                result.put(fieldName, resultItem);
                countDownLatch.countDown();
                continue;
            }
            ThreadUtil.startThread(() -> {
                InputStream is = null;
                try {
                    is = item instanceof FileItem ? ((FileItem) item).getInputStream() : ((Part) item).getInputStream();
                    BIOStreamUtil.streamWriteFile(is, filePath, sysFileName);
                    resultItem.setSuccess(true);
                    result.put(fieldName, resultItem);
                } catch (IOException e) {
                    log.info("No-Multipart:" + e.getMessage());
                } finally {
                    countDownLatch.countDown();
                    BIOStreamUtil.closeStream(is);
                }
            });
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new ServiceException(e);
        }
        return result;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy