springboot 上传文件报错:java.io.IOException: The temporary upload location [/tmp/tomcat.xxx] is not valid

本文介绍了SpringBoot项目中遇到的文件上传异常,即由于/Linux系统的tmpwatch命令删除了Tomcat的临时文件目录导致的问题。解决方案包括重启SpringBoot应用或修改配置以指定新的临时文件目录。作者提醒开发者注意上线项目的预警机制和问题排查。

前言: 

之前上线半个月后的项目,突然发现图片上传的接口有问题,无法上传,提示java.io.IOException: The temporary upload location [/tmp/tomcat.7538204303517105479.8899/work/Tomcat/localhost/main_service] is not valid的异常,经过百度,才知道这个是springboot项目文件上传的一个坑。

正文:

我们先复现下问题:

1.用postman调用图片上传的接口

2. 登录xshell去查看下日志

2019-06-05 11:04:35.904 [http-nio-8899-exec-10] ERROR o.a.c.c.C.[.[.[/main_service].[dispatcherServlet]  Servlet.service() for servlet [dispatcherServlet] in context with path [/main_service] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.7538204303517105479.8899/work/Tomcat/localhost/main_service] is not valid] with root cause
java.io.IOException: The temporary upload location [/tmp/tomcat.7538204303517105479.8899/work/Tomcat/localhost/main_service] is not valid
	at org.apache.catalina.connector.Request.parseParts(Request.java:2821)
	at org.apache.catalina.connector.Request.getParts(Request.java:2754)
	at org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1098)
	at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:94)
	at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:87)
	at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:87)
	at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1175)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1010)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapper
<think> 我们正在解决Spring Boot生产环境中出现的文件上传错误: "Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat...] is not valid" 根据引用[1]和常见经验,该错误通常是因为临时上传目录(示例中为/tmp/tomcat...)不存在或不可访问所致。在生产环境中,由于系统可能定期清理/tmp目录,导致Tomcat临时目录被删除,从而引发此问题。 解决方案的核心是:为Spring Boot应用指定一个稳定的临时目录(不在/tmp下,或者确保该目录不会被系统清理)。 具体步骤: 1. 在application.properties(或application.yml)中显式配置Multipart临时目录: ```properties spring.servlet.multipart.location=/data/upload/tmp ``` 将`/data/upload/tmp`替换为你希望的实际路径,确保该目录存在且应用有读写权限。 2. 如果使用嵌入式Tomcat,还可以通过配置Tomcat的临时目录来达到同样目的(因为文件上传的临时目录默认使用Tomcat的工作目录): ```properties server.tomcat.basedir=/data/tomcat ``` 这样,Tomcat的工作目录(包括临时上传目录)将被设置在`/data/tomcat`下,避免被系统清理。 3. 确保配置的目录存在并赋予正确的权限: ```bash mkdir -p /data/upload/tmp # 或者 /data/tomcat chmod 755 /data/upload/tmp # 根据实际情况设置权限,确保应用用户可读写 ``` 4. 重启应用。 注意:如果是在容器化环境中(如Docker),需要确保该目录是持久化的,或者通过挂载卷来保持目录持久存在。 解释:Spring Boot在处理文件上传时会使用临时目录来存储上传的临时文件。默认情况下,这个目录在Tomcat的工作目录下(位于系统的临时目录如/tmp)。而/tmp目录可能在系统重启或定时任务中被清理,导致目录丢失。 因此,通过配置一个稳定的目录,可以避免此问题。 参考:[引用1]中提到该错误的原因是临时上传目录无效(不存在或不可访问),因此我们通过配置一个持久有效的目录来解决问题。 相关问题: 1. 如何更改Spring Boot中文件上传的其他配置(如最大文件大小)? 2. 在Docker容器中如何持久化Spring Boot的临时目录? 3. 如何监控Spring Boot应用的文件上传目录以预防磁盘空间不足? </think> ### 解决 Spring Boot 文件上传临时目录无效错误 当 Spring Boot 应用出现以下错误时: ```log Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.8994705980655212485.17002/work/Tomcat/localhost/ROOT] is not valid ``` **问题原因**: 此错误表示 Spring Boot 用于存储文件上传的临时目录失效或丢失。Linux 系统通常会定期清理 `/tmp` 目录,导致 Tomcat 创建的临时目录被删除(尤其在服务器重启后)[^1]。 #### 解决方案步骤: 1. **手动创建临时目录(临时修复)** ```bash mkdir -p /tmp/tomcat.8994705980655212485.17002/work/Tomcat/localhost/ROOT chmod 777 /tmp/tomcat.8994705980655212485.17002/work/Tomcat/localhost/ROOT ``` *说明*:手动重建错误提示中的目录即可恢复服务(需在每次服务器重启后重复操作)。 2. **配置自定义持久化目录(推荐方案)** 在 `application.properties` 中指定永久目录: ```properties # 配置自定义临时目录路径 spring.servlet.multipart.location=/data/upload-tmp ``` 创建目录并授权: ```bash sudo mkdir -p /data/upload-tmp sudo chown -R tomcat:tomcat /data/upload-tmp # 替换为实际运行用户 sudo chmod 755 /data/upload-tmp ``` 3. **配置 Tomcat 基础目录(替代方案)** ```properties # 设置Tomcat工作目录 server.tomcat.basedir=/var/myapp/tomcat ``` 4. **添加系统启动脚本(自动化方案)** 创建 Systemd 服务文件(如 `/etc/systemd/system/myapp.service`): ```ini [Unit] Description=My Spring Boot App [Service] ExecStartPre=/bin/mkdir -p /tmp/tomcat.8994705980655212485.17002/work/Tomcat/localhost/ROOT ExecStart=/usr/bin/java -jar /opt/myapp.jar ``` #### 关键要点: - ✅ **核心问题**:临时目录 `/tmp` 易被系统清理 - ✅ **终极方案**:配置 `spring.servlet.multipart.location` 指向非 `/tmp` 的持久化目录 - ✅ **生产建议**:使用固定目录 + 定期清理脚本(避免磁盘写满) ---
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心的码字达

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值