SpringBoot上传文件:临时文件目录不存在

问题:
springboot项目,部署到服务器后,运行一段时间后,处理一些文件上传的接口时,后报异常。


Could not parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.7333297176951596407.9000/work/Tomcat/localhost/ROOT] is not valid。

即临时文件目录不存在.

原因:
查阅资料后,发现是linux对’/tmp’下文件自动清理的原因。
在springboot项目启动后,系统会在‘/tmp’目录下自动的创建几个目录(我的项目是以下的文件夹)

  1. hsperfdata_root,
  2. tomcat.************.8080,(结尾是项目的端后
  3. tomcat-docbase.*********.8080。
    Multipart(form-data)的方式处理请求时,默认就是在第二个目录下创建临时文件的。

主要原因可能是在于系统默认配置会自动清理对一段时间内未操作的临时文件目录,导致上传时无法查询到临时文件目录。

CentOS6以下系统(含)使用watchtmp + cron来实现定时清理临时文件的效果,这点在CentOS7发生了变化,在CentOS7下,系统使用systemd管理易变与临时文件,与之相关的系统服务有3个:

systemd-tmpfiles-setup.service :Create Volatile Files and Directories
systemd-tmpfiles-setup-dev.service:Create static device nodes in /dev
systemd-tmpfiles-clean.service :Cleanup of Temporary Directories

相关的配置文件也有3个地方:
/etc/tmpfiles.d/.conf
/run/tmpfiles.d/
.conf
/usr/lib/tmpfiles.d/*.conf
/tmp目录的清理规则主要取决于/usr/lib/tmpfiles.d/tmp.conf文件的设定,默认的配置内容为:


#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

# See tmpfiles.d(5) for details

# Clear tmp directories separately, to make them easier to override
v /tmp 1777 root root 10d           #   清理/tmp下10天前的目录和文件
v /var/tmp 1777 root root 30d       #   清理/var/tmp下30天前的目录和文件

# Exclude namespace mountpoints created with PrivateTmp=yes
x /tmp/systemd-private-%b-*
X /tmp/systemd-private-%b-*/tmp
x /var/tmp/systemd-private-%b-*
X /var/tmp/systemd-private-%b-*/tmp

解决方法
有4种:
1.重启项目,再次自动生成临时文件目录,但如果在一段时间内未操作临时文件目录,可能会再次出现问题。
2.配置Multipart(form-data)请求时的临时文件目录位置,不要放在/tmp下。


@Configuration
public class MultipartConfig {
    /**
     * 文件上传临时路径
     */
    @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        String location = System.getProperty("user.dir") + "/data/tmp";
        File tmpFile = new File(location);
        if (!tmpFile.exists()) {
            tmpFile.mkdirs();
        }
        factory.setLocation(location);
        return factory.createMultipartConfig();
    }
}

3.在服务器中手动创建对应目录。
4.添加系统配置,让系统不会自动清除以 tomcat.* 格式的临时文件目录。
x /tmp/tomcat.* 添加到上述文件中即可.

你可能感兴趣的:(springboot)