Временное расположение загрузки [/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. https://github.com/spring-projects/spring-boot/issues/9616

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

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

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

33
0
32 901
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

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

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

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

Обновлять

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

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

Это свойство устарело. Вместо этого используйте spring.servlet.multipart.location

Vivek Sethi 30.10.2018 06:42

Для тех, кто хочет указать местоположение, отличное от "tmp", я использовал это: spring.servlet.multipart.location: ${user.dir} в моем application.yml

Vivek Sethi 30.10.2018 11:24
spring.servlet.multipart.location не работает при весенней загрузке 1.5.9, но spring.http.multipart.location работает.
Daniel Dai 13.12.2018 08:25

@mavlarn, это временное решение, как решить его навсегда, даже если это показывает ошибку, новое местоположение не найдено.

Deva 29.07.2019 16:38

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

Mavlarn 01.08.2019 06:01

Я использую весеннюю загрузку 1.5.9, и я настроил spring.http.multipart.location=/upload, new File("/upload").canWrite() по-прежнему возвращает false, хотя я могу выполнять загрузку файлов из нескольких частей, как это возможно?

Dimitri Kopriwa 03.04.2020 14:15

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

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

Что делать, если эта ошибка на UAT или Production? мы не можем перезапускать этот сервер снова и снова na.

Deva 30.07.2019 10:52

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

Mavlarn 01.08.2019 06:02

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

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

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

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

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

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

Rajdeep 07.03.2019 10:14

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

nanospeck 06.01.2020 04:27

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

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

nanospeck 06.01.2020 04:27

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

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

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

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

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

Вы можете, как предложено в принятом ответе, указать его где-нибудь еще, кроме / tmp, и он будет работать нормально (хотя, что касается очистки, вам, возможно, следует прочитать здесь https://github.com/spring-projects/spring-boot/issues/9983 - теперь вы полагаетесь на очистку весенних ботинок, которая, правда, должен работает нормально).

Но почему папка на самом деле исчезла? Далее @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 .... были просто не приняты там, где я работаю.

Возможно, вы закодируете тело формы запроса POST с помощью Тип содержимого: multipart / form-data HTTP-заголовок.

Вы должны отправить Тип содержимого: application / x-www-form-urlencoded POST

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

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

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

Другие вопросы по теме