The springboot upload failed to find the temporary directory and reported an error
1. Problem description
According to the feedback of online users, the upload file function suddenly reported an error. After checking the log file, the error message is:
failed to parse multipart servlet request; nested exception is java.lang.RuntimeException: java.nio.file.NoSuchFileException: /tmp/undertow.8099.1610110889708131476/undertow1171565914461190366upload
2. Cause investigation
Originally, when launching the spring boot
application through java - jar
in the linux
operating system, a temporary directory will be created by default in the /tmp
directory (in Windows operating system, C:\users\default\appdata\ local\temp
), and the temporary directory is generally in the format of undertow. Port.*
(if the Tomcat
container is Tomcat.Port.*
, this article will take undertow
as an example, and Tomcat
is the same.) , files need to be converted into temporary files and stored here when uploading. However, if the files in the /tmp
directory are not used for more than 10 days, they will be automatically cleaned up by the system. Therefore, the above problems do not occur in the directory when uploading again.
3. Problem recurrence
Since the temporary directory will be created automatically when the service is started, restart the service in the local or test environment, delete the undertow.Port.*
(if Tomcat
, it is Tomcat.Port.*
) directory generated under /tmp
, and upload the file again.
4. Solution
1. Manually create the temporary directory (not recommended)
mkdir -p /tmp/undertow.8099.1610110889708131476/undertow1171565914461190366upload
PS: if the file is not uploaded for more than 10 days again, the same problem will occur. The symptoms are not the root cause.
2. Modify Linux system configuration (not recommended)
vim /usr/lib/tmpfiles.d/tmp.con
# Add at the end of the file, which means that the folder at the beginning of undertow will not be cleaned up
x /tmp/undertow*
PS: if multiple servers are deployed, each server needs to be modified.
3. Modify spring boot configuration file (recommended)
spring:
servlet:
multipart:
# Specify a custom upload directory
location: /mnt/tmp
PS: when using this method, you must ensure that /MNT/tmp
exists. If it does not exist, the same error will occur. Therefore, it needs to be judged every time the service is started. If the directory exists, it will be ignored, and if it does not exist, it will be created. The code is as follows:
@Slf4j
@Configuration
public class MultipartConfig {
@Value("${spring.servlet.multipart.location}")
private String fileTempDir;
@Bean
MultipartConfigElement multipartConfigElement() {
String os = System.getProperty("os.name");
// windows
if(os.toLowerCase().startsWith("win")){
fileTempDir = "C:" + fileTempDir;
}
log.info("fileTempDir:{}", fileTempDir);
MultipartConfigFactory factory = new MultipartConfigFactory();
File tmpDirFile = new File(fileTempDir);
// Determine whether the folder exists
if (!tmpDirFile.exists()) {
//Create folder
boolean mkdirSuccess = tmpDirFile.mkdirs();
log.info("create temp dir,result:{}", mkdirSuccess);
}
factory.setLocation(fileTempDir);
return factory.createMultipartConfig();
}
}