Ответ 1
Храните его где угодно в доступном месте кроме папки проекта IDE, а также папки развертывания сервера, по причинам, указанным в ответе Только загруженное изображение после обновления страницы:
Изменения в папке проекта IDE не сразу отражаются в рабочей папке сервера. Там есть фоновая работа в среде IDE, которая заботится о том, чтобы рабочая папка сервера синхронизировалась с последними обновлениями (это в терминах IDE, называемых "публикация" ). Это основная причина проблемы, которую вы видите.
В коде реального мира существуют ситуации, когда сохранение загруженных файлов в папке развертывания webapp не будет работать вообще. Некоторые серверы (по умолчанию или по конфигурации) не расширяют развернутый WAR файл в локальную файловую систему на диске, а полностью заполняют память. Вы не можете создавать новые файлы в памяти без основного редактирования развернутого WAR файла и его повторного развертывания.
Даже когда сервер расширяет развернутый файл WAR в локальную файловую систему на диске, все вновь созданные файлы теряются при повторном развертывании или даже простом перезапуске, просто потому, что эти новые файлы не являются частью исходной WAR файл.
Для меня или для кого-то еще не важно, где именно на локальной файловой системе на диске будет сохранено, если вы не используйте метод getRealPath()
. Использование этого метода в любом случае вызывает тревогу.
Путь к месту хранения, в свою очередь, может быть определен многими способами. Вы должны сделать все это самостоятельно. Возможно, именно здесь возникла ваша путаница, потому что вы как-то ожидали, что сервер сделает это все автоматически. Обратите внимание, что @MultipartConfig(location)
указывает не конечный пункт назначения загрузки, но временное хранилище для размера файла case превышает порог памяти.
Таким образом, путь к окончательному месту хранения может быть определен одним из следующих способов:
-
Запрограммированный:
File uploads = new File("/path/to/uploads");
-
Переменная окружения через
SET UPLOAD_LOCATION=/path/to/uploads
:File uploads = new File(System.getenv("UPLOAD_LOCATION"));
-
Аргумент VM во время запуска сервера через
-Dupload.location="/path/to/uploads"
:File uploads = new File(System.getProperty("upload.location"));
-
*.properties
запись файла какupload.location=/path/to/uploads
:File uploads = new File(properties.getProperty("upload.location"));
-
web.xml
<context-param>
с именемupload.location
и значением/path/to/uploads
:File uploads = new File(getServletContext().getInitParameter("upload.location"));
-
Если есть, используйте предоставленное сервером местоположение, например. в JBoss AS/WildFly:
File uploads = new File(System.getProperty("jboss.server.data.dir"), "uploads");
В любом случае вы можете легко ссылаться и сохранять файл следующим образом:
File file = new File(uploads, "somefilename.ext");
try (InputStream input = part.getInputStream()) {
Files.copy(input, file.toPath());
}
Или, если вы хотите автогенерировать уникальное имя файла, чтобы пользователи не могли переписывать существующие файлы с одинаковым именем:
File file = File.createTempFile("somefilename-", ".ext", uploads);
try (InputStream input = part.getInputStream()) {
Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
Как получить part
в JSP/Servlet в ответ на Как загрузить файлы на сервер с помощью JSP/Servlet? и как получить part
в JSF ответил в Как загрузить файл с помощью JSF 2.2 < h: inputFile > ? Где сохраненный файл?
Примечание: используйте не Part#write()
, поскольку он интерпретирует путь относительно места временного хранения, определенного в @MultipartConfig(location)
.
См. также:
- Как сохранить загруженный файл в JSF (JSF-target, но принцип почти такой же)
- Простейший способ обслуживания статических данных вне сервера приложений в веб-приложении Java (в случае, если вы хотите его вернуть)
- Как временно сохранить сгенерированный файл в веб-приложении на основе сервлетов