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



Я разработал веб-приложение 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-это путь к контексту в этом servletcontext.



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


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

624   2  

2 ответов:

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

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

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

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

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

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

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

Однако, если вам действительно нужно позже обслуживать этот файл, вам либо понадобится контейнер, определенный механизм "монтирования" внешних каталогов в ваше веб-приложение (Glassfish как "альтернативные корни doc", другие имеют аналогичные концепции), или вам нужно будет написать сервлет/фильтр для обслуживания хранилища файлов за пределами вашего веб-приложения. ЭтоFileServlet является довольно полным, и, как вы можете видеть, создание собственного, хотя и не сложно, не тривиально, чтобы сделать это правильно.

Правка:

Основная суть та же, но вместо того, чтобы использовать "getRealPath", просто используйте "getInitParameter".

Итак:

String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;
И отправляйся своей дорогой.

Отредактируйте еще раз:

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

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

Comments

    Ничего не найдено.