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

The temporary upload location [/tmp/tomcat.4296537502689403143.5000/work/Tomcat/localhost/ROOT] is not valid

我正在使用 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

我在 Spring Github 问题中发现了这个问题。 https://github.com/spring-projects/spring-boot/issues/9616

但我对此仍有疑问。

  1. 我没有在我的应用程序中使用文件上传功能。但是日志说 "Could not parse multipart servlet request" 这是为什么? (当我的应用程序使用 RestTemplate(Post 方法)
  2. 时出现异常
  3. 为了解决异常,我重新启动了我的应用程序,但它没有立即运行。虽然我重新启动了我的应用程序,但它引用了不存在的 tomcat 目录。重新启动一天后,它起作用了。我猜该目录被缓存在 Spring 的某个地方,否则..?

请帮帮我!

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

您可以在 application.yml 中设置多部分位置:

spring:
  http:
    multipart:
      location: /data/upload_tmp

更新

根据 Vivek Sethi 上面的评论 属性 对我不起作用,但下面的评论。

spring.servlet.multipart.location=/data/upload_tmp

我解决这个问题的方法是重新启动应用程序,添加 -java.tmp.dir=/path/to/application/temp/ 并在我的应用程序文件夹中创建一个 /temp/ 文件夹。

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

问题已经得到解答,但也许我可以帮助别人。我也遇到了这个问题,但是 none 的建议解决方案对我有用。

我们结合 Zuul 使用 Spring boot,归结为:

  1. 停止应用程序
  2. 停止 Zuul
  3. 删除 /tmp 文件夹中的 tomcat 相关文件夹(这是我们 tomcat 文件夹的存储位置,其他文件夹可能不同)
  4. 重启 Zuul
  5. 重新启动应用程序

简单地重新启动应用程序对我们不起作用,因为它指向一个不存在的文件夹:名称缓存在某处。

使用Zuul时,请求先经过Zuul,然后在那里抛出异常。

在微服务架构中,问题可能是由于 Zuul 超时。我遇到了同样的问题并尝试了上面讨论的所有内容但没有奏效。在 Zuul 属性中使用 dfs-bulk-service.ribbon.ReadTimeout=90000 配置增加超时后,它工作正常。这里的 dfs-bulk-service 是我用 Zuul 配置的微服务名称 api 网关。

此问题已于几天前修复。
Spring 引导: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.

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

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

我们也遇到这个问题很久了,我只是想详细说明上面接受的答案中与 2) 有关的一些内容。

所以,这里的问题是 tomcat 的临时文件夹突然 "disappears" 而不是声称的 "POSTs in general" 而是专门针对多部分请求。于是

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

涉及到这里。正如@Frankstar 上面所说,在最近的 spring-boot 代码中,这是由 "always creating the tmp-folder if it's not there" 修复的,当然也可以工作 if 你是 运行 a超级新鲜 spring-boot。

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

但是为什么文件夹真的消失了?再往下@Hasan Sawan 说 "It is a bug between spring and tomcat servers"。但真的是..?

对我们来说,解决方案是配置这些东西。 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

添加一行

X /tmp/tomcat.* 

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

验证这一点
# SYSTEMD_LOG_TARGET=console SYSTEMD_LOG_LEVEL=debug /usr/bin/systemd-tmpfiles --clean 2>&1 | grep tomcat 

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

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

注意:上面提到的 "restart" 或 # mkdir /tmp/tomcat... 的解决方案在我工作的地方根本不被接受。

您可以通过 Content-Type 对 POST 请求的 body 形式进行编码:multipart/form-data HTTP header .

你应该发送一个 Content-Type: application/x-www-form-urlencoded POST

对我来说,它使用了正确的依赖项(如果使用 java/maven)

       <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

检查 C:/ 中的文件夹,如果没有一个名为 temp 的文件夹,则创建它 C:/temp , ,这个解决方案对我有用