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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50523407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:36:46  来源:igfitidea点击:

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

springspring-bootembedded-tomcat-8

提问by Sooyoung Park

I am using Spring Boot 1.5.13 version.

我使用的是 Spring Boot 1.5.13 版本。

I got the exception message like below.

我收到如下异常消息。

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

I founded out this issue in Spring Github Issues. https://github.com/spring-projects/spring-boot/issues/9616

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

But I still have questions of that.

但我对此仍有疑问。

  1. I am not using File Upload things in my app. But the log says that "Could not parse multipart servlet request" why is that? (I got the exception when my app uses RestTemplate (Post method)
  2. To solve the exception, I rebooted my app but It did not work right away. Although i rebooted my app, it had referenced the tomcat directory which was not exist. After a day after rebooting, it worked. I guess the directory was cached in somewhere in Spring or else..?
  1. 我没有在我的应用程序中使用文件上传的东西。但是日志说“无法解析多部分 servlet 请求”为什么会这样?(当我的应用程序使用 RestTemplate(Post 方法)时出现异常
  2. 为了解决异常,我重新启动了我的应用程序,但它没有立即工作。虽然我重新启动了我的应用程序,但它引用了不存在的 tomcat 目录。重新启动后一天后,它起作用了。我猜这个目录被缓存在 Spring 的某个地方,或者其他..?

Please Help me out!

请帮帮我!

回答by Mavlarn

  1. The http POST methods will use these temp locations to store the post data.
  2. Some OSs like centOS will delete the temp dir frequently. So, even you set that location's permission, after some time that dir will be removed by the OS. And after you reboot, the temp dir will be different.
  1. http POST 方法将使用这些临时位置来存储发布数据。
  2. 一些操作系统如centOS 会经常删除临时目录。因此,即使您设置了该位置的权限,一段时间后该目录也会被操作系统删除。重新启动后,临时目录会有所不同。

You can set the multipart location in application.yml:

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

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

Update

更新

As per comment by Vivek Sethi above property didn't work for me but the below one.

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

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

回答by Hasan Sawan

Just restart your application in the server. It is a bug between spring and tomcat servers. Once the application restarts it consume a temp directory in the server.

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

回答by Ola Aronsson

We've had this problem since long too, I just wanted to eloborate some stuff relating to 2) in above accepted answer.

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

So, the problem here is that tomcat's temp folders suddenly "disappears" and not for "POSTs in general" as is claimed but for multipart requests specifically. Thus

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

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

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

is involved here. As @Frankstar said above, in recent spring-boot code this is fixed by "always creating the tmp-folder if it's not there", works too of course ifyou're running a super-fresh spring-boot.

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

You can, as suggested as in the accepted answer, point it to somewhere else other than /tmp and it will work fine (though, regarding cleanup you should perhaps have a read here https://github.com/spring-projects/spring-boot/issues/9983- you are now reliant on spring-boots cleanup which, though, shouldwork fine).

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

But why did the folder actually disappear? Further down @Hasan Sawan says that "It is a bug between spring and tomcat servers". But is it really..?

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

For us the solution was to configure this stuff. OSes such as CentOS will use (see for instance https://www.thegeekdiary.com/centos-rhel-7-how-tmpfiles-clean-up-tmp-or-var-tmp-replacement-of-tmpwatch)) systemd for cleaning up /tmp - and anythingnot accessed within 10 days will be cleaned by the default setting.

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

Thus on our redhat servers we solved this be editing

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

/usr/lib/tmpfiles.d/tmp.conf

adding a line like

添加一行,如

X /tmp/tomcat.* 

to solve this issue. You can verify this too using

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

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

where you will see that these directories will now be ignored.

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

There is also this fix for systems whereas tmpwatch is used instead https://javahotfix.blogspot.com/2019/03/spring-boot-micro-services-tmptomcat.html

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

Note : the solutions mentioned above to "restart" or to just # mkdir /tmp/tomcat.... were simply not accepted where I work.

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

回答by Frankstar

This Issue was fixed a couple of days ago.
Spring Boot: 2.1.4 or 1.5.20

这个问题是几天前修复的。
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.

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

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

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

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

回答by Edwin Lambregts

Question has already been answered, but maybe I can help someone out. I had this problem as well, but none of the suggested solutions worked for me.

问题已经得到解答,但也许我可以帮助某人。我也有这个问题,但没有一个建议的解决方案对我有用。

We use Spring boot in combination with Zuul, which boiled down to the following:

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

  1. Stop the application
  2. Stop Zuul
  3. Remove tomcat related folders in the /tmp folder (this is where our tomcat folders were stored, might be different for others)
  4. Restart Zuul
  5. Restart the application
  1. 停止应用
  2. 停止祖尔
  3. 删除/tmp文件夹中的tomcat相关文件夹(这是我们存放tomcat文件夹的地方,其他的可能不一样)
  4. 重启 Zuul
  5. 重新启动应用程序

Simply restarting the application did not work for us, as it was pointing to a non-existing folder: the name was cached somewhere.

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

When using Zuul, the request go through Zuul first and throw exception there.

使用 Zuul 时,请求首先通过 Zuul 并在那里抛出异常。

回答by Rajdeep

In micro services architecture, problem can be due to Zuul timeout. I faced the same issue and tried everything above discussed but did not work. After I increased timeout with dfs-bulk-service.ribbon.ReadTimeout=90000 configuartion in Zuul properties, it worked fine. Here dfs-bulk-service is my micro service name configured with Zuul as api gateway.

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

回答by user3450862

What I did to solve the issue was to relaunch the application adding -java.tmp.dir=/path/to/application/temp/and creating a /temp/folder in my application folder.

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

回答by Green Lei

You maybe encode the form body of the POST request by Content-Type: multipart/form-datahttp header .

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

You should send a Content-Type: application/x-www-form-urlencodedPOST

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

回答by Llama

For me it was using the correct dependency (if using java/maven)

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

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

回答by Shivaji Mutkule

It is recommended to specify custom directory path for temp storage through spring (or server) configuration.

建议通过spring(或server)配置为临时存储指定自定义目录路径。

But quick hack would be to create the mentioned directory and provide the read/write permissions as

但是快速破解是创建提到的目录并提供读/写权限

mkdir -p /tmp/tomcat.4296537502689403143.5000/work/Tomcat/localhost/ROOT

chmod 755 /tmp/tomcat.4296537502689403143.5000/work/Tomcat/localhost/ROOT

tomcat.xxxxxxxxxxxx.xxxx - This will be different on each server. Use this directory name from your server error.

tomcat.xxxxxxxxxxxx.xxxx - 这在每个服务器上都不同。使用服务器错误中的此目录名称。