App下載

Java代碼實(shí)現(xiàn)SpringBoot單文件和多文件的上傳功能

猿友 2021-07-26 11:14:51 瀏覽數(shù) (2025)
反饋

一、公共文件存儲(chǔ)代碼

1.FileUploadUtils.java

package com.springcloud.blog.admin.util.file;

/**
 * @description: 文件上傳工具類
 * @author: youcong
 * @time: 2020/9/28 11:34
 */

import com.springcloud.blog.admin.exception.file.FileNameLengthLimitExceededException;
import com.springcloud.blog.admin.exception.file.FileSizeLimitExceededException;
import com.springcloud.blog.admin.exception.file.InvalidExtensionException;
import com.springcloud.blog.admin.util.DateUtils;
import com.springcloud.blog.admin.util.IdUtils;
import com.springcloud.blog.admin.util.StringUtils;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

public class FileUploadUtils {
    /**
     * 默認(rèn)大小 50M
     */
    public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;

    /**
     * 默認(rèn)的文件名最大長(zhǎng)度 100
     */
    public static final int DEFAULT_FILE_NAME_LENGTH = 100;

    /**
     * 默認(rèn)上傳的地址
     */
    private static String defaultBaseDir = "D://test//";

    /**
     * 資源映射路徑 前綴
     */
    public static String resource_prefix = "D://test//";

    public static void setDefaultBaseDir(String defaultBaseDir) {
        FileUploadUtils.defaultBaseDir = defaultBaseDir;
    }

    public static String getDefaultBaseDir() {
        return defaultBaseDir;
    }

    /**
     * 以默認(rèn)配置進(jìn)行文件上傳
     *
     * @param file 上傳的文件
     * @return 文件名稱
     * @throws Exception
     */
    public static final String upload(MultipartFile file) throws IOException {
        try {
            return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        } catch (Exception e) {
            throw new IOException(e.getMessage(), e);
        }
    }


    /**
     * 文件上傳
     *
     * @param baseDir          相對(duì)應(yīng)用的基目錄
     * @param file             上傳的文件
     * @param allowedExtension 上傳文件類型
     * @return 返回上傳成功的文件名
     * @throws FileSizeLimitExceededException       如果超出最大大小
     * @throws FileNameLengthLimitExceededException 文件名太長(zhǎng)
     * @throws IOException                          比如讀寫文件出錯(cuò)時(shí)
     * @throws InvalidExtensionException            文件校驗(yàn)異常
     */
    public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
            throws FileUploadBase.FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
            InvalidExtensionException {
        int fileNamelength = file.getOriginalFilename().length();
        if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) {
            throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
        }

        assertAllowed(file, allowedExtension);

        String fileName = extractFilename(file);

        File desc = getAbsoluteFile(baseDir, fileName);
        file.transferTo(desc);
        String pathFileName = getPathFileName(baseDir, fileName);
        return pathFileName;
    }

    /**
     * 編碼文件名
     */
    public static final String extractFilename(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
        return fileName;
    }

    private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
        File desc = new File(uploadDir + File.separator + fileName);

        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        if (!desc.exists()) {
            desc.createNewFile();
        }
        return desc;
    }

    private static final String getPathFileName(String uploadDir, String fileName) throws IOException {
        int dirLastIndex = defaultBaseDir.length() + 1;
        String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
        String pathFileName = resource_prefix + "/" + currentDir + "/" + fileName;
        return pathFileName;
    }

    /**
     * 文件大小校驗(yàn)
     *
     * @param file 上傳的文件
     * @return
     * @throws FileSizeLimitExceededException 如果超出最大大小
     * @throws InvalidExtensionException
     */
    public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
            throws FileSizeLimitExceededException, InvalidExtensionException {
        long size = file.getSize();
        if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) {
            throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
        }

        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) {
            if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) {
                throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
                        fileName);
            } else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) {
                throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
                        fileName);
            } else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) {
                throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
                        fileName);
            } else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) {
                throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
                        fileName);
            } else {
                throw new InvalidExtensionException(allowedExtension, extension, fileName);
            }
        }

    }

    /**
     * 判斷MIME類型是否是允許的MIME類型
     *
     * @param extension
     * @param allowedExtension
     * @return
     */
    public static final boolean isAllowedExtension(String extension, String[] allowedExtension) {
        for (String str : allowedExtension) {
            if (str.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 獲取文件名的后綴
     *
     * @param file 表單文件
     * @return 后綴名
     */
    public static final String getExtension(MultipartFile file) {
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if (StringUtils.isEmpty(extension)) {
            extension = MimeTypeUtils.getExtension(file.getContentType());
        }
        return extension;
    }
}

2.FileUtils.java

package com.springcloud.blog.admin.util.file;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;

/**
 * 文件處理工具類
 *
 * @author youcong
 */
public class FileUtils extends org.apache.commons.io.FileUtils {
    public static String FILENAME_PATTERN = "[a-zA-Z0-9_\-\|\.\u4e00-\u9fa5]+";

    /**
     * 輸出指定文件的byte數(shù)組
     *
     * @param filePath 文件路徑
     * @param os       輸出流
     * @return
     */
    public static void writeBytes(String filePath, OutputStream os) throws IOException {
        FileInputStream fis = null;
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0) {
                os.write(b, 0, length);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 刪除文件
     *
     * @param filePath 文件
     * @return
     */
    public static boolean deleteFile(String filePath) {
        boolean flag = false;
        File file = new File(filePath);
        // 路徑為文件且不為空則進(jìn)行刪除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 文件名稱驗(yàn)證
     *
     * @param filename 文件名稱
     * @return true 正常 false 非法
     */
    public static boolean isValidFilename(String filename) {
        return filename.matches(FILENAME_PATTERN);
    }

    /**
     * 下載文件名重新編碼
     *
     * @param request  請(qǐng)求對(duì)象
     * @param fileName 文件名
     * @return 編碼后的文件名
     */
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
            throws UnsupportedEncodingException {
        final String agent = request.getHeader("USER-AGENT");
        String filename = fileName;
        if (agent.contains("MSIE")) {
            // IE瀏覽器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐瀏覽器
            filename = new String(fileName.getBytes(), "ISO8859-1");
        } else if (agent.contains("Chrome")) {
            // google瀏覽器
            filename = URLEncoder.encode(filename, "utf-8");
        } else {
            // 其它瀏覽器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

3.MimeTypeUtils.java

package com.springcloud.blog.admin.util.file;

/**
 * @description:
 * @author: youcong
 * @time: 2020/9/28 11:37
 */
public class MimeTypeUtils {
    public static final String IMAGE_PNG = "image/png";

    public static final String IMAGE_JPG = "image/jpg";

    public static final String IMAGE_JPEG = "image/jpeg";

    public static final String IMAGE_BMP = "image/bmp";

    public static final String IMAGE_GIF = "image/gif";

    public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};

    public static final String[] FLASH_EXTENSION = {"swf", "flv"};

    public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
            "asf", "rm", "rmvb"};

    public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};

    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
            // 圖片
            "bmp", "gif", "jpg", "jpeg", "png",
            // word excel powerpoint
            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
            // 壓縮文件
            "rar", "zip", "gz", "bz2",
            // 視頻格式
            "mp4", "avi", "rmvb",
            // pdf
            "pdf"};

    public static String getExtension(String prefix) {
        switch (prefix) {
            case IMAGE_PNG:
                return "png";
            case IMAGE_JPG:
                return "jpg";
            case IMAGE_JPEG:
                return "jpeg";
            case IMAGE_BMP:
                return "bmp";
            case IMAGE_GIF:
                return "gif";
            default:
                return "";
        }
    }
}

4.FileException.java

package com.springcloud.blog.admin.exception.file;

import com.springcloud.blog.admin.exception.BaseException;

/**
 * @description: 文件信息異常類
 * @author: youcong
 * @time: 2020/9/28 11:41
 */
public class FileException extends BaseException {
    private static final long serialVersionUID = 1L;

    public FileException(String code, Object[] args) {
        super("file", code, args, null);
    }

}

5.FileNameLengthLimitExceededException.java

package com.springcloud.blog.admin.exception.file;

/**
 * @description:文件名稱超長(zhǎng)限制異常類
 * @author: youcong
 * @time: 2020/9/28 11:41
 */
public class FileNameLengthLimitExceededException extends FileException {
    private static final long serialVersionUID = 1L;

    public FileNameLengthLimitExceededException(int defaultFileNameLength) {
        super("upload.filename.exceed.length", new Object[]{defaultFileNameLength});
    }
}

6.FileSizeLimitExceededException.java

package com.springcloud.blog.admin.exception.file;

/**
 * @description: 文件名大小限制異常類
 * @author: youcong
 * @time: 2020/9/28 11:42
 */
public class FileSizeLimitExceededException extends FileException {
    private static final long serialVersionUID = 1L;

    public FileSizeLimitExceededException(long defaultMaxSize) {
        super("upload.exceed.maxSize", new Object[]{defaultMaxSize});
    }
}

7.InvalidExtensionException.java

package com.springcloud.blog.admin.exception.file;

/**
 * @description: 文件上傳錯(cuò)誤異常類
 * @author: youcong
 * @time: 2020/9/28 11:42
 */

import org.apache.commons.fileupload.FileUploadException;

import java.util.Arrays;

public class InvalidExtensionException extends FileUploadException {
    private static final long serialVersionUID = 1L;

    private String[] allowedExtension;
    private String extension;
    private String filename;

    public InvalidExtensionException(String[] allowedExtension, String extension, String filename) {
        super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
        this.allowedExtension = allowedExtension;
        this.extension = extension;
        this.filename = filename;
    }

    public String[] getAllowedExtension() {
        return allowedExtension;
    }

    public String getExtension() {
        return extension;
    }

    public String getFilename() {
        return filename;
    }

    public static class InvalidImageExtensionException extends InvalidExtensionException {
        private static final long serialVersionUID = 1L;

        public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) {
            super(allowedExtension, extension, filename);
        }
    }

    public static class InvalidFlashExtensionException extends InvalidExtensionException {
        private static final long serialVersionUID = 1L;

        public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) {
            super(allowedExtension, extension, filename);
        }
    }

    public static class InvalidMediaExtensionException extends InvalidExtensionException {
        private static final long serialVersionUID = 1L;

        public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) {
            super(allowedExtension, extension, filename);
        }
    }

    public static class InvalidVideoExtensionException extends InvalidExtensionException {
        private static final long serialVersionUID = 1L;

        public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) {
            super(allowedExtension, extension, filename);
        }
    }
}

8.BaseException.java

package com.springcloud.blog.admin.exception;

/**
 * 基礎(chǔ)異常
 *
 * @author youcong
 */
public class BaseException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    /**
     * 所屬模塊
     */
    private String module;

    /**
     * 錯(cuò)誤碼
     */
    private String code;

    /**
     * 錯(cuò)誤碼對(duì)應(yīng)的參數(shù)
     */
    private Object[] args;

    /**
     * 錯(cuò)誤消息
     */
    private String defaultMessage;

    public BaseException(String module, String code, Object[] args, String defaultMessage) {
        this.module = module;
        this.code = code;
        this.args = args;
        this.defaultMessage = defaultMessage;
    }

    public BaseException(String module, String code, Object[] args) {
        this(module, code, args, null);
    }

    public BaseException(String module, String defaultMessage) {
        this(module, null, null, defaultMessage);
    }

    public BaseException(String code, Object[] args) {
        this(null, code, args, null);
    }

    public BaseException(String defaultMessage) {
        this(null, null, null, defaultMessage);
    }

    public String getModule() {
        return module;
    }

    public String getCode() {
        return code;
    }

    public Object[] getArgs() {
        return args;
    }

    public String getDefaultMessage() {
        return defaultMessage;
    }
}

二、單文件上傳代碼

@PostMapping("/post/uploadFile")
@ApiOperation("文章上傳特色圖片")
public ResponseBaseDTO<String> uploadFile(@RequestParam("file") MultipartFile file) {
    logger.info("/post/uploadFile");
    try {

        String fileUrl = FileUploadUtils.upload(file);
        if (fileUrl != null) {
            return ResponseBaseDTO.createSuccResp(fileUrl);
        }
        return ResponseBaseDTO.createFailResp(fileUrl);
    } catch (Exception e) {
        logger.error("/post/uploadFile", e);
        return ResponseBaseDTO.createFailResp(e.getMessage());
    }
}

三、多文件上傳代碼

@PostMapping("/batchImportsUsers")
@ApiOperation("批量導(dǎo)入用戶數(shù)據(jù)小時(shí)")
public ResponseBaseDTO<String> batchImportsUsers(MultipartFile[] uploadFiles) {
    if (uploadFiles.length > 0) {
        for (int i = 0; i < uploadFiles.length; i++) {
            try {
                importUserExcelData(uploadFiles[i]);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ResponseBaseDTO.createSuccResp();
    }
    return ResponseBaseDTO.createFailResp(e.getMessage());
}

以上就是關(guān)于使用 Java 代碼來(lái)實(shí)現(xiàn) SpringBoot 單文件與多文件上傳的詳細(xì)內(nèi)容,想要了解更多關(guān)于 SpringBoot 框架其他方面的應(yīng)用內(nèi)容請(qǐng)關(guān)注W3Cschool其它相關(guān)文章!


0 人點(diǎn)贊