Как хранить файл на сервере (веб-контейнер) через 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.

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

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

11
задан Mr_and_Mrs_D 6 September 2013 в 17:34
поделиться

2 ответа

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

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

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

13
ответ дан 3 December 2019 в 02:19
поделиться

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

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

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

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

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

Изменить:

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

Итак:

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

И вперед.

Снова отредактируйте:

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

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

20
ответ дан 3 December 2019 в 02:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: