【问题标题】:The temporary upload location [/tmp/tomcat.4296537502689403143.5000/work/Tomcat/localhost/ROOT] is not valid临时上传位置[/tmp/tomcat.4296537502689403143.5000/work/Tomcat/localhost/ROOT]无效
【发布时间】:2018-11-04 12:16:24
【问题描述】:

我使用的是 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. 我没有在我的应用程序中使用文件上传功能。但是日志说“无法解析多部分 servlet 请求”为什么会这样? (当我的应用使用 RestTemplate(Post 方法)时出现异常
  2. 为了解决这个异常,我重新启动了我的应用程序,但它没有立即工作。虽然我重新启动了我的应用程序,但它引用了不存在的 tomcat 目录。重启一天后,它工作了。我猜该目录被缓存在 Spring 的某个地方,否则......?

请帮帮我!

【问题讨论】:

    标签: spring spring-boot embedded-tomcat-8


    【解决方案1】:
    1. http POST 方法将使用这些临时位置来存储发布数据。
    2. centOS 等一些操作系统会频繁删除临时目录。因此,即使您设置了该位置的权限,一段时间后该目录也会被操作系统删除。重新启动后,临时目录会有所不同。

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

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

    更新

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

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

    【讨论】:

    • 此属性已弃用。请改用spring.servlet.multipart.location
    • 对于希望指定非“tmp”位置的人,我在 application.yml 中使用了这个:spring.servlet.multipart.location: ${user.dir}
    • spring.servlet.multipart.location 不适用于 Spring Boot 1.5.9,但 spring.http.multipart.location 可以。
    • @mavlarn,这是临时解决方案,我们如何永久解决,即使这显示错误 new location not found。
    • 我不认为这是一个临时解决方案。我们需要确保我们的应用程序可以在不同的系统上运行。 CentOS 有时会删除临时目录。所以我们需要定义一个我们使用的临时目录位置。这样它就不会受到系统在临时目录上的行为的影响。
    【解决方案2】:

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

    【讨论】:

    • 如果 UAT 或生产上的错误怎么办?我们不能一次又一次地重启这个服务器。
    • 正如我上面提到的,这个问题的原因是,centOS会经常删除临时目录。当您的应用程序正在运行,但 centOS 删除了您的临时目录时,就会出现这样的错误。所以,重启你的应用程序可以工作一段时间。但是一段时间后,又会出现这个错误。
    【解决方案3】:

    此问题已在几天前修复。
    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.
    

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

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

    【讨论】:

      【解决方案4】:

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

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

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

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

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

      但是为什么文件夹实际上消失了?再往下,@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
      

      添加一行

      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

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

      【讨论】:

        【解决方案5】:

        问题已经得到解答,但也许我可以帮助别人。我也遇到了这个问题,但是建议的解决方案都不适合我。

        我们将Spring boot与Zuul结合使用,归结为以下几点:

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

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

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

        【讨论】:

        • 同意,在微服务架构中,问题可能出在 Zuul 上。我遇到了同样的问题并尝试了上面讨论的所有内容,但没有奏效。在 Zuul 属性中使用 dfs-bulk-service.ribbon.ReadTimeout=90000 配置增加超时后,它工作正常。
        • 请注意,上面注释中的 'dfs-bulk-service' 是实际的服务名称,您可能会有所不同。参考:cloud.spring.io/spring-cloud-netflix/multi/…
        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

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

          【讨论】:

          【解决方案8】:

          您可以通过 Content-Type: multipart/form-data 对 POST 请求的表单正文进行编码 http 标头。

          您应该发送 Content-Type: application/x-www-form-urlencoded POST

          【讨论】:

            【解决方案9】:

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

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

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-12-27
                • 1970-01-01
                • 2018-12-26
                • 2013-09-04
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多