在项目中偶尔会遇到 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>