解决上传时临时路径不存在问题

            在项目中偶尔会遇到 java.nio.file.NoSuchFileException:/tmp/undertow*** 的问题,这是因为临时文件在一段时间(10天)未使用则会被自动清理,这种情况下需要要么重启服务器,要么在配置文件内配置临时文件路劲。

注: tocmat启动也可以编辑 catalina 内的 catalina_tmpdir 路劲,set "CATALINA_TMPDIR=%CATALINA_BASE%\temp"

spring:
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB
      location: /opt/nurse/undertow

        但是这样需要手动创建手动创建该目录,容易遗忘,可以新建一个配置类,服务启动时自动创建该目录(liunx 下使用这个就可以了)

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.MultipartConfigElement;
import java.io.File;

/**
 * 检查文件上传缓存文件夹是否存在,不存在则创建
 * @author pw
 */
@Configuration
public class MultipartConfig {
    @Value("${spring.servlet.multipart.location:/tmp/undertow}")
    private String tempDir;

    @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        File file = new File(tempDir);
        // 判断文件夹是否存在
        if (!file.exists()) {
            //创建文件夹
            file.mkdirs();
        }
        factory.setLocation(tempDir);
        return factory.createMultipartConfig();
    }
}

引入JAR

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

        这样也有一个问题,如果是win系统,你会发现该代码执行后,上诉报错还会发生,调试后发现,创建的文件夹路劲D:/tmp/***,读取的路劲C:/tmp/**,为了找到这一问题的情况,我们需要找到上传文件时,如何读取的配置,通过调试可以发现读取到的配置可以发现,配置的路劲前已经自动添加了一个C盘的路劲

        继续深入,我们可以找到 MultiPartParserDefinition 文件夹下的 tempFileLocation 参数,发现参数已经发生变化,而77行,则是赋值的地方:

        在这里,我们可以发现,当无法读取配置或者配置为空的情况下,使用默认的配置;当配置的路径为绝对路劲,使用配置路径;而当配置路径非绝对路劲的情况下,则通过当前部署的默认临时路劲的盘符拼接上配置的路劲,得到最终的绝对路劲

故配置类也需要加上一样的判断,保证最终创建的路劲和使用的路劲一致。注,该方法会导入undertow,与gateway冲突,因此不能被gateway引用。


import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.MultipartConfigElement;
import java.io.File;

/**
 * 检查文件上传缓存文件夹是否存在,不存在则创建
 * @author pw
 */
@Configuration
public class MultipartConfig {
    @Value("${spring.servlet.multipart.location:/tmp/undertow}")
    private String tempDir;
/**
*该baen不能被gateway引用,这时可以使用下面被注释的方法
*/
    @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        Path locFile = Paths.get(tempDir);
        if(!locFile.isAbsolute()) {
            MultiPartParserDefinition parse = new MultiPartParserDefinition();
            locFile = parse.getTempFileLocation().resolve(tempDir);
        }
        File file =locFile.toFile();
        // 判断文件夹是否存在
        if (!file.exists()) {
            //创建文件夹
            file.mkdirs();
        }
        factory.setLocation(tempDir);
        return factory.createMultipartConfig();
    }

//    @Bean
//    MultipartConfigElement multipartConfigElement() {
//        MultipartConfigFactory factory = new MultipartConfigFactory();
//        File locFile = new File(tempDir);
//        String os = System.getProperty("os.name");
//        if (!locFile.isAbsolute() && os.toLowerCase().startsWith("windows")) {
//            tempDir = "C:"+tempDir;
//        }
//        locFile = new File(tempDir);
//        // 判断文件夹是否存在
//        if (!locFile.exists()) {
//            //创建文件夹
//            locFile.mkdirs();
//        }
//        factory.setLocation(tempDir);
//        return factory.createMultipartConfig();
//    }
}

引入JAR

<!-- 注意不能被gateway引用-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值