Как хранить файл на сервере (веб-контейнер) через веб-приложение Java EE?

StackOverflow https://stackoverflow.com/questions/2663204

Вопрос

Я разработал веб-приложение Java EE. Это приложение позволяет пользователю загружать файл с помощью браузера. После того, как пользователь загрузил свой файл, это приложение впервые хранит загруженный файл на сервере (на котором он работает), а затем обрабатывает его.

В настоящее время я сохраняю файл на сервере следующим образом:

try {
    // formFile represents the uploaded file
    FormFile formFile = programForm.getTheFile();
    String path = getServlet().getServletContext().getRealPath("") + "/"
        + formFile.getFileName();
    System.out.println(path);
    file = new File(path);
    outputStream = new FileOutputStream(file);
    outputStream.write(formFile.getFileData());
}

где formFile представляет загруженный файл.

Теперь проблема в том, что она работает нормально на некоторых серверах, но на некоторых серверах getServlet().getServletContext().getRealPath("") возвращается null так что последний путь, который я получаю, это null/filename И файл не хранится на сервере.

Когда я проверил API для ServletContext.getRealPath() Метод, я нашел следующее:

public java.lang.String getRealPath(java.lang.String path)

Возвращает строку, содержащую реальный путь для данного виртуального пути. Например, путь "/index.html" Возвращает абсолютный путь к файлову на файловой системе сервера будет обслуживаться запросом для "http://host/contextPath/index.html", где ContextPath - это контекстный путь этого сервелеска.

Возвращенный реальный путь будет в форме, соответствующей компьютерной и операционной системе, на которой работает контейнер сервлета, включая правильные сепараторы пути. Этот метод возвращает NULL, если сервлетный контейнер не может перевести виртуальный путь к реальному пути по любой причине (например, когда содержимое доступен из архива .war).

Итак, есть ли какой-либо другой способ, которым я могу хранить файлы на этих серверах, которые также возвращаются null для getServlet().getServletContext().getRealPath("")

Это было полезно?

Решение

Написание файловой системы из контейнера Java EE на самом деле не рекомендуется, особенно если вам нужно обработать письменные данные:

  • Это не транзакционный
  • Это наносит вред по мобильности (что, если вы находитесь в кластерной среде)
  • Это требует настройки внешних параметров для целевого местоположения

Если это опция, я бы хранил файлы в базе данных или использую репозиторий JCR (например, Джекраббит).

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

По спецификации, единственный «реальный» путь, который вы гарантируете, чтобы получить форму, контейнер сервлета - это каталог TEMP.

Вы можете получить это через ServletContext.gerAttribute("javax.servlet.context.tempdir"). Отказ Тем не менее, эти файлы не видны веб-контексту (т.е. вы не можете опубликовать простой URL для доставки этих файлов), и файлы никак не гарантированы, чтобы выдержать веб-приложение или перезапуск сервера.

Если вам просто нужно место для хранения рабочего файла на короткое время, то это будет работать нормально для вас.

Если вам действительно нужен каталог, вы можете сделать его параметром конфигурации (либо переменной среды, свойство Java (т.е. java -Dyour.file.here=/tmp/files ...), параметр контекста, установленный в Web.xml, параметр конфигурации, хранящийся в вашей базе данных через веб-форму и т. Д.). Затем это зависит от Deployer, чтобы настроить этот каталог для вас.

Однако, если вам нужно позже служить на этот файл, вам будет либо нужен механизм контейнера для «установки» внешних каталогов в ваше веб-приложение (Glassfish как «альтернативные корни DOC», другие имеют аналогичные понятия), или вы будете Нужно написать сервлет / фильтр для обслуживания файлового магазина за пределами вашего веб-приложения. Этот Filesevlet. Вполне полный, и, как видите, создавая свой собственный, пока не сложно, не тривиально сделать это правильно.

Редактировать:

Базовый гид такой же, но вместо того, чтобы использовать «GetrealPath», просто используйте «GetInitParameter».

Так:

String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;

И быть на вашем пути.

Редактировать еще раз:

Что касается содержания пути, я бы дал ему абсолютный путь. В противном случае вам нужно будет знать, где сервер приложений устанавливает свой путь по умолчанию к EUREUCTION, и каждый сервер приложений вполне может использовать разные каталоги. Например, я считаю, что рабочий каталог для Glassfish - это каталог конфигурации рабочего домена. Не особенно очевидный выбор.

Итак, используйте абсолютный путь, как определенно. Таким образом, вы знаете, где будут проходить файлы, и вы можете управлять разрешениями доступа на уровне ОС для этого каталога, если это необходимо.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top