Место временной загрузки [/tmp/tomcat.4296537502689403143.5000/work/Tomcat/localhost/ROOT] недопустимо.

Я использую версию 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 Issues. https://github.com/spring-projects/spring-boot/issues/9616

Но у меня все еще есть вопросы по этому поводу.

  1. Я не использую функции загрузки файлов в своем приложении. Но в журнале написано, что «Не удалось проанализировать составной запрос сервлета», почему это так? (Я получил исключение, когда мое приложение использует RestTemplate (метод Post)
  2. Чтобы устранить исключение, я перезагрузил свое приложение, но оно не сработало сразу. Хотя я перезагрузил свое приложение, оно ссылалось на несуществующий каталог tomcat. Через сутки после перезагрузки заработало. Я предполагаю, что каталог был кэширован где-то весной или еще ..?

Пожалуйста, помогите мне!


person Sooyoung Park    schedule 25.05.2018    source источник


Ответы (10)


  1. Методы http POST будут использовать эти временные местоположения для хранения данных публикации.
  2. Некоторые ОС, такие как centOS, часто удаляют временный каталог. Таким образом, даже если вы установите разрешение для этого местоположения, через некоторое время этот каталог будет удален ОС. И после перезагрузки временный каталог будет другим.

Вы можете установить составное местоположение в application.yml:

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

Обновить

Согласно комментарию Вивека Сетхи, вышеприведенное свойство не сработало для меня, но ниже.

spring.servlet.multipart.location=/data/upload_tmp
person Mavlarn    schedule 25.05.2018
comment
Это свойство устарело. Вместо этого используйте spring.servlet.multipart.location - person Vivek Sethi; 30.10.2018
comment
Для тех, кто хочет указать местоположение, отличное от tmp, я использовал это: spring.servlet.multipart.location: ${user.dir} в моем application.yml - person Vivek Sethi; 30.10.2018
comment
spring.servlet.multipart.location не работает с весенней загрузкой 1.5.9, но spring.http.multipart.location работает. - person Daniel Dai; 13.12.2018
comment
@mavlarn, это временное решение, как решить постоянно, даже если это показывает ошибку, новое местоположение не найдено. - person Deva; 29.07.2019
comment
Я не думаю, что это временное решение. Нам нужно убедиться, что наше приложение может работать в другой системе. CentOS когда-нибудь удалит временный каталог. Итак, нам нужно определить местоположение временного каталога, которое мы используем. Чтобы на него не влияло поведение системы во временном каталоге. - person Mavlarn; 01.08.2019
comment
Я использую весеннюю загрузку 1.5.9, и я настроил spring.http.multipart.location=/upload, new File("/upload").canWrite() по-прежнему возвращать false, в то время как я могу загружать составные файлы, как это возможно? - person Dimitri Kopriwa; 03.04.2020

Просто перезапустите приложение на сервере. Это ошибка между серверами spring и tomcat. После перезапуска приложения оно использует временный каталог на сервере.

person Hasan Sawan    schedule 27.07.2018
comment
Что делать, если эта ошибка на UAT или Production? мы не можем перезапускать этот сервер снова и снова na. - person Deva; 30.07.2019
comment
Как я упоминал выше, причина этой проблемы в том, что CentOS часто удаляет временный каталог. Когда ваше приложение запущено, но CentOS удалила ваш временный каталог, тогда будет такая ошибка. Таким образом, перезапуск вашего приложения может работать некоторое время. Но через какое-то время опять будет эта ошибка. - person Mavlarn; 01.08.2019

Эта проблема была исправлена ​​пару дней назад.
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>

person Frankstar    schedule 19.04.2019

У нас была эта проблема уже давно, я просто хотел уточнить некоторые вещи, касающиеся 2) в принятом выше ответе.

Итак, проблема здесь в том, что временные папки tomcat внезапно «исчезают», и не для «POST-сообщений в целом», как утверждается, а конкретно для составных запросов. Таким образом

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

здесь участвует. Как сказал @Frankstar выше, в недавнем коде весенней загрузки это исправлено путем «всегда создавать папку tmp, если ее там нет», конечно, тоже работает, если вы используете супер-свежую пружину -ботинок.

Вы можете, как было предложено в принятом ответе, указать его в другом месте, кроме /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

добавить строку типа

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.... просто не принимались там, где я работаю.

person Ola Aronsson    schedule 26.07.2019

На вопрос уже был дан ответ, но, возможно, я смогу помочь кому-то. У меня тоже была эта проблема, но ни одно из предложенных решений не помогло мне.

Мы используем Spring boot в сочетании с Zuul, что сводилось к следующему:

  1. Остановить приложение
  2. Остановить Зуул
  3. Удалите папки, связанные с tomcat, в папке /tmp (здесь хранились наши папки tomcat, у других они могут отличаться)
  4. Перезапустите Зуул
  5. Перезапустите приложение

Просто перезапустить приложение у нас не получилось, так как оно указывало на несуществующую папку: имя где-то закешировалось.

При использовании Zuul запрос сначала проходит через Zuul и генерирует там исключение.

person Edwin Lambregts    schedule 17.08.2018
comment
Согласен, в архитектуре микросервисов проблема может быть из-за Zuul. Я столкнулся с той же проблемой и попробовал все, что обсуждалось выше, но не сработало. После того, как я увеличил время ожидания с помощью конфигурации dfs-bulk-service.ribbon.ReadTimeout=90000 в свойствах Zuul, все заработало нормально. - person Rajdeep; 07.03.2019
comment
Обратите внимание, что «dfs-bulk-service» в приведенном выше комментарии — это фактическое имя службы, которое для вас будет другим. Ссылка: cloud.spring.io/spring-cloud-netflix/multi/ - person nanospeck; 06.01.2020

Чтобы решить эту проблему, я перезапустил приложение, добавив -java.tmp.dir=/path/to/application/temp/ и создав папку /temp/ в папке моего приложения.

person user3450862    schedule 26.07.2018

В архитектуре микросервисов проблема может быть связана с тайм-аутом Zuul. Я столкнулся с той же проблемой и попробовал все, что обсуждалось выше, но не сработало. После того, как я увеличил время ожидания с помощью конфигурации dfs-bulk-service.ribbon.ReadTimeout=90000 в свойствах Zuul, все заработало нормально. Здесь dfs-bulk-service — это имя моего микросервиса, настроенного с Zuul в качестве шлюза API.

person Rajdeep    schedule 07.03.2019
comment
Обратите внимание, что «dfs-bulk-service» в приведенном выше ответе — это фактическое имя службы, которое для вас будет другим. Ссылка: cloud.spring.io/spring-cloud-netflix/multi/ - person nanospeck; 06.01.2020

Вы можете закодировать тело формы запроса POST с помощью Content-Type: multipart/form-data http-заголовка.

Вы должны отправить Content-Type: application/x-www-form-urlencoded POST

person Green Lei    schedule 13.08.2019

Для меня использовалась правильная зависимость (при использовании java/maven)

       <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
person Llama    schedule 20.02.2020

проверьте папку в C:/, если нет ни одной папки с именем temp, создайте ее C:/temp, это решение сработало для меня

person m Piroli    schedule 18.02.2021