SpringBoot接收上传文件及打成Jar包失败的解决方案

本文共有6783个字,页面加载耗时0.001秒,关键词:

在本地IDE运行是上传功能通过VoteMangeController.class.getClassLoader().getResource("")).getPath()确定上传目录是正常的,但是打成 jar 包放到服务器通过 java -jar xxxxx.jar 运行时报错。

具体报错信息:

java.io.FileNotFoundException: /Users/zhang/Codes/java/javaCode/xxx/target/tomcat-
static/tomcat/work/Tomcat/localhost/ROOT/./file:/Users/zhang/Codes/java/javaCode/x
xxxx/target/xxxxx.jar!/BOOT-INF/classes!/static/uploads/20d4530867a02b46926e2d562b
ef9d78.jpeg (No such file or directory)

0.可能的原因

jar文件不能被修改

1.解决方案

1.1 思路

将文件上传到static/uploads并将static目录设置为静态资源目录(static-locations)

1.2 application.yml

my:
  upload-path: /uploads/  # 上传的路径,相对于/static/
  allow-max-size: 5 * 1024 *1024 # 单文件最大多大,单位字节
  allow-ext: jpg,jpeg,png,gif # 允许什么类型的文件,英文逗号分隔

spring:
  servlet:
    multipart:
      max-request-size: 10MB # 设置最大的最大请求大小
      max-file-size: 10MB    # 设置单文件的最大请求大小
      enabled: true
  web:
    resources:
      static-locations: classpath:/static/,file:/static/ # 非常重要,一定要设置

1.3 UploadUtils

为了方便以后的使用,将获取服务器上传的物理路径和校验文件合法性的功能封装成一个工具类

项目里面使用到了hu-tool,使用前应先在pom.xml添加依赖

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>4.1.1</version>
</dependency>
package com.hsmus.upload.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.digest.DigestUtil;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.List;

/**
 * @author Mustard
 * @date 2021/1/22
 * @time 14:53
 */
@Component
public class UploadUtils {


    private static List<String> allowExt;

    private static Long allowMaxSize;

    private static final String staticPath = "/static/";

    public static void setAllowExt(List<String> ext) {
        allowExt = ext;
    }

    public static void setAllowMaxSize(Long size) {
        allowMaxSize = size;
    }

    /**
     * 校验上传文件的合法性
     * 使用前务必执行setAllowExt,setAllowMaxSize
     *
     * @param file
     * @return 校验结果
     */
    public static Boolean check(MultipartFile file) {
        if (file == null || file.isEmpty()) return false;
        String ext = FileUtil.extName(file.getOriginalFilename());
        return file.getSize() <= allowMaxSize && allowExt.contains(ext);
    }

    public static String getPath(String uploadPath) throws FileNotFoundException {
        File path = new File(ResourceUtils.getURL("classpath:").getPath());
        if (!path.exists()) {
            path = new File("");
        }

        File fileUploadPath = new File(path.getAbsolutePath() + staticPath + uploadPath);
        if (!fileUploadPath.exists()) {
            fileUploadPath.mkdirs();
        }
        return fileUploadPath.getAbsolutePath() + File.separator;
    }

    public static String getFilePath(String uploadPath, String fileName) throws FileNotFoundException {
        return getPath(uploadPath) + fileName;
    }


    public static String getFilePath(String uploadPath, MultipartFile file, FileNameGenerator generator) throws FileNotFoundException {
        return getPath(uploadPath) + generator.generator(file);
    }

    public static String getFilePath(String uploadPath, MultipartFile file) throws FileNotFoundException {
        return getFilePath(uploadPath, file, (file1 -> DigestUtil.md5Hex(FileUtil.extName(file1.getOriginalFilename()) + new Date().getTime()) +
                '.' + FileUtil.extName(file1.getOriginalFilename())));
    }

    /**
     * 文件名生成器
     */
    interface FileNameGenerator {
        /**
         * 生成文件名
         *
         * @param file 文件
         * @return 文件名
         */
        String generator(MultipartFile file);
    }
}

1.4 UploadController

建立控制器对外提供访问,控制器中包含单文件及多文件上传,表单名为file

package com.hsmus.upload.controller;

import com.hsmus.upload.entity.R;
import com.hsmus.upload.utils.UploadUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Mustard
 * @date 2021/1/22
 * @time 14:36
 */
@CrossOrigin
@RestController
@RequestMapping("app/upload")
public class UploadController {

    @Value("${my.upload-path}")
    private String uploadPath;

    @Value("#{'${my.allow-ext}'.split(',')}")
    private List<String> allowExt;

    @Value("#{${my.allow-max-size}}")
    private String allowMaxSize;

    @GetMapping("")
    public R test() {
        return R.ok(uploadPath);
    }

    /**
     * 单文件上传
     * @param file
     * @return
     */
    @PostMapping("single")
    public R singleUpload(@RequestParam(value = "file", required = false) MultipartFile file) {
        UploadUtils.setAllowExt(allowExt);
        UploadUtils.setAllowMaxSize(Long.valueOf(allowMaxSize));
        try {
            String path = receiveUpload(file);
            return R.ok("success").put("data", path);
        } catch (IOException e) {
            e.printStackTrace();
            return R.error(e.getMessage());
        }
    }

    /**
     * 多文件上传
     * @param files
     * @return
     */
    @PostMapping("multi")
    public R multiUpload(@RequestParam(value = "file", required = false) MultipartFile[] files) {
        UploadUtils.setAllowExt(allowExt);
        UploadUtils.setAllowMaxSize(Long.valueOf(allowMaxSize));
        if (files == null || files.length == 0) {
            return R.error("请上传文件");
        }
        List<String> paths = new ArrayList<>();
        for (MultipartFile file : files) {
            try {
                String path = receiveUpload(file);
                paths.add(path);
            } catch (IOException e) {
                e.printStackTrace();
                return R.error(e.getMessage());
            }
        }
        return R.ok().put("data", paths);
    }

    private String receiveUpload(MultipartFile file) throws IOException {
        Boolean check = UploadUtils.check(file);
        if (check) {
            String path = UploadUtils.getFilePath(uploadPath, file);
            File dest = new File(path);
            file.transferTo(dest);
            return uploadPath + dest.getName();
        }
        return null;
    }

}

2.完整代码

GitHub

扫码在手机查看