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

2 ответов


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

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

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


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

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

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

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

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

изменить:

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

Так:

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

и иди своей дорогой.

изменить еще раз:

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

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