前言

众所周知,Spring Boot 是目前非常流行的 Java 快速开发框架,取代了传统的 XML 配置方式(如 SSM/SSH 时代),使得企业应用可以零 XML 配置跑起一个 jar 包。使用 Spring Boot 可以通过各种注解进行配置,并且它内部集成了 Tomcat/Undertow 的 Web 服务器,无需像以前那样需要单独安装服务器,只需将项目打包成 war 包放入容器中即可运行,这大大提升了使用效率和性能表现。

尽管 Spring Boot 简化了很多操作,但它仍然基于 Spring、SpringMVC 和 Web 相关框架的类和 API。因此,开发者仍需对这些有所了解,否则可能会遇到无法预知的“坑”。

问题产生的背景

测试环境有一个系统,是基于SpringBoot,测试人员在操作时,发现上不传了图片/文件,测试人员说之前是可以上传,不知为什么今天上传不了。

问题的分析

既然发现了问题,那就从程序输出的日志上找原因吧,找到服务对应的日志,通过简单的grep命令,找到如下一段异常:

1
2
3
4
org.springframework.web.multipart.MultipartException: 
Could not parse multipart servlet request; nested exception is java.io.IOException:
The temporary upload location
[/tmp/tomcat.1312576899112123874.8089/work/Tomcat/localhost/ROOT] is not valid

这个错误提示是:“临时上传的目录非法”。开发也很奇怪,项目里明明没有配置这个目录,为什么会用到这个目录呢?

原来,SpringBoot框架中在上传附件时,会先缓存到本地磁盘上(注意:http流是一次消费的,后续无法在次使用,所以要先缓存起来),以便后续的复用。而在没有明确指定缓存的目录时,SpringBoot默认是在/tmp目录下的。

从这个报错看是这个目录可能不存在/或者权限不够之类。进入服务器后,结果发现没有这个目录,为什么这个目录会不见了呢?

查找linux的资料,发现linux有这样的机制:

在linux中,tmp目录可以删除;该目录用于存储临时性的文件,该目录会默认清理指定天数未用的文件,系统重启会清空目录,“/tmp”目录默认清理10天未用的文件,“/var/tmp”目录默认清理30天未用的文件。

解决的办法

1. 临时解决办法(不便于及时改配置部署)

重启下应用服务,让应用服务重新生成目录(SpringBoot中的tomcat在重启后,会在/tmp目录下,重新生成一个临时的目录) – 但以后还是会面临时被清除。

2. 修改linux的配置,让其不清除这类文件(可能会堆积,不建议)

1
2
3
vim /usr/lib/tmpfiles.d/tmp.conf
# 添加下面一行
/tmp/tomcat.*

3. 增加启动参数

启动springBoot程序,添加使用指定临时目录的启动参数 -java.tmp.dir=你想的目录

4. 修改SpringBoot的properties文件

找到项目的application.properties文件,在基中添加以下配置,让其使用其他目录,不使用/tmp目录

1
2
3
server.tomcat.basedir=你想的目录

spring.http.multipart.location=你想的目录

ps:因作者能力有限,有错误的地方请见谅

  • 喜欢这篇文章的话可以用快捷键 Ctrl + D 来收藏本页
× 请我吃糖~
打赏二维码