临时上传位置[/tmp/tomcat.4296537502689403143.5000/work/Tomcat/localhost/ROOT]无效

Soo*_*ark 20 spring spring-boot embedded-tomcat-8

我使用的是Spring Boot 1.5.13版本.

我得到了如下的异常消息.

Could not parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.4296537502689403143.5000/work/Tomcat/localhost/ROOT] is not valid
Run Code Online (Sandbox Code Playgroud)

我在Spring Github Issues中找到了这个问题. https://github.com/spring-projects/spring-boot/issues/9616

但我仍然对此有疑问.

  1. 我没有在我的应用中使用文件上传内容.但是日志说"无法解析多部分servlet请求"为什么会这样?(当我的应用程序使用RestTemplate时,我得到了异常(Post方法)
  2. 为了解决这个异常,我重启了我的应用程序,但它没有立即工作.虽然我重新启动了我的应用程序,但它引用了不存在的tomcat目录.重启后一天,它工作.我想这个目录是在Spring的某个地方缓存的,否则......?

请帮帮我!

Mav*_*arn 21

  1. http POST方法将使用这些临时位置来存储发布数据.
  2. 像centOS这样的操作系统会经常删除临时目录.因此,即使您在一段时间后设置了该位置的权限,该操作系统也会删除该目录.重启后,临时目录会有所不同.

您可以在application.yml中设置multipart位置:

spring:
  http:
    multipart:
      location: /data/upload_tmp
Run Code Online (Sandbox Code Playgroud)

  • 不推荐使用此属性.请改用"spring.servlet.multipart.location" (7认同)
  • 对于想要指定非“ tmp”位置的用户,我在我的application.yml中使用了以下命令:spring.servlet.multipart.location:$ {user.dir} (2认同)
  • spring.servlet.multipart.location不能在Spring Boot 1.5.9上运行,但是spring.http.multipart.location可以。 (2认同)

小智 8

只需在服务器中重新启动应用程序即可。这是spring和tomcat服务器之间的错误。应用程序重新启动后,它将在服务器中使用一个临时目录。

  • 如果 UAT 或生产出现错误怎么办?我们不能一次又一次地重新启动该服务器na。 (2认同)

Fra*_*tar 6

这个问题是几天前修复的。
Spring Boot:2.1.4 或 1.5.20

This version bump fixes an issue when the tmp dir was deleted
by the OS and the spring boot app tries to handle a multifile
upload.
Run Code Online (Sandbox Code Playgroud)

问题:https : //github.com/spring-projects/spring-boot/issues/9616

https://github.com/MeiSign/Copy-Pasta/commit/1200fb353a48a3d0c92038dee7cced7cebf3acfe


Ola*_*son 6

我们也有这个问题很久了,我只是想在上面接受的答案中阐述一些与 2) 相关的东西。

因此,这里的问题是 tomcat 的临时文件夹突然“消失”,而不是像声称的那样用于“一般的 POST”,而是专门用于多部分请求。因此

spring.servlet.multipart.location/spring.http.multipart.location

涉及到这里。正如@Frankstar 上面所说,在最近的 spring-boot 代码中,这是通过“如果不存在则始终创建 tmp 文件夹”来解决的,当然,如果您运行的是超级新鲜的 spring-boot。

您可以按照已接受的答案中的建议,将其指向 /tmp 以外的其他地方,它会正常工作(不过,关于清理,您可能应该在这里阅读https://github.com/spring-projects/spring -boot/issues/9983 - 您现在依赖于 spring-boots 清理,但应该可以正常工作)。

但为什么文件夹实际上消失了?再往下@Hasan Sawan 说“这是 spring 和 tomcat 服务器之间的错误”。但真的是..吗?

对我们来说,解决方案是配置这些东西。CentOS 等操作系统将使用(例如参见https://www.thegeekdiary.com/centos-rhel-7-how-tmpfiles-clean-up-tmp-or-var-tmp-replacement-of-tmpwatch))systemd用于清理 /tmp - 10 天内未访问的任何内容将被默认设置清理。

因此在我们的 redhat 服务器上我们解决了这个问题

/usr/lib/tmpfiles.d/tmp.conf
Run Code Online (Sandbox Code Playgroud)

添加一行,如

X /tmp/tomcat.* 
Run Code Online (Sandbox Code Playgroud)

来解决这个问题。您也可以使用

# SYSTEMD_LOG_TARGET=console SYSTEMD_LOG_LEVEL=debug /usr/bin/systemd-tmpfiles --clean 2>&1 | grep tomcat 
Run Code Online (Sandbox Code Playgroud)

您将看到这些目录现在将被忽略。

系统也有此修复程序,而使用 tmpwatch 代替https://javahotfix.blogspot.com/2019/03/spring-boot-micro-services-tmptomcat.html

注意:上面提到的“重新启动”或只是 # mkdir /tmp/tomcat... 的解决方案在我工作的地方根本不被接受。