在项目中碰到了一个报错:
1 | org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.4565031138659477751.9888/work |
原因
SpringBoot项目启动后会在/tmp
目录下生成一个目录:tomcat.************.8080
,其中结尾的8080是项目tomcat的端口号,使用Multipart(form-data)的方式上传文件时,会在这个目录下面创建临时文件。
由于Linux系统会定期对tmp
下的文件夹进行清除,文件夹在长时间(默认10天)没有使用的情况下,就会被系统自动删除掉。/tmp
目录的清理规则主要取决于/usr/lib/tmpfiles.d/tmp.conf
文件的设定,默认的配置内容为:
1 | # Clear tmp directories separately, to make them easier to override |
根据上面的分析,如果上传文件的功能长时间没有使用,导致临时目录被删掉,则会抛出前面的那个异常了。
解决办法
方案一
直接重启项目, 会重新生成一个上面所说的临时文件夹。
方案二
在配置文件中配置tomcat的临时目录:
1 | server.tomcat.basedir=/home/temp |
该目录是用来存放Tomcat的日志、Dump等文件的临时文件夹,默认没有指定则会使用/tmp
目录。
如果server.tomcat.basedir
指定的目录不存在,项目启动的时候会自动创建。
方案三
在配置文件中配置multipart文件上传的临时目录:
1 | spring.servlet.multipart.location=/home/temp |
spring.servlet.multipart.location
这个配置在旧版本的SpringBoot里是叫spring.http.multipart.location
。
对于multipart文件上传的临时目录,这个设置的优先级要高于server.tomcat.basedir
,即如果spring.servlet.multipart.location
有配置则以spring.servlet.multipart.location
配置的目录为准,没有配置则会取server.tomcat.basedir
配置的目录。
注意:spring.servlet.multipart.location
配置的目录需要手动创建。
方案四
使用注解的方式配置:
1 |
|
这个和方案三的原理是一样的,不同之处是不需要手动去创建文件夹,因为代码里加了一个判断。
Servlet3.0后spring上传文件的机制
Spring 在处理上传文件的时候,会将当前文件的大小跟 fileSizeThreshold
(默认为0)这个值比较,如果大于fileSizeThreshold
则将文件保存在临时文件夹中,否则直接将文件放入内存中。 所以在上传文件过程中会对临时路径进行验证,如果临时路径不是文件夹或者不存在都将抛出异常。location临时路径可以通过spring.servlet.multipart.location
指定。当不指定的时候会默认取servlet上下文临时存储目录:javax.servlet.context.tempdir
,当servlet上下文临时存储目录不指定时会被赋值为tomcat的基本工作目录,tomcat基本工作目录可以由server.tomcat.basedir
指定(linux 系统默认为在tmp
目录下)。
v1.5.2