Как сохранить загруженный файл в JSF

Я загружаю файл в формате JSF. Я использую Томагавк <t:inputFileUpload> для этого, но тот же вопрос применим, например, к PrimeFaces <p:fileUpload> и JSF 2.2 <h:inputFile>,

У меня есть код бина ниже:

private UploadedFile uploadedFile; // +getter+setter

public String save() throws IOException {
    String name = uploadedFile.getName();
    System.out.println("File name: " + name);

    String type = uploadedFile.getContentType();
    System.out.println("File type: " + type);

    long size = uploadedFile.getSize();
    System.out.println("File size: " + size);  

    InputStream stream = uploadedFile.getInputStream();
    byte[] buffer = new byte[(int) size];  
    stream.read(buffer, 0, (int) size);  
    stream.close();  
}

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

2 ответа

Решение

getInputStream() Метод загруженного файла представляет содержимое файла.

InputStream input = uploadedFile.getInputStream();

Вам нужно скопировать его в файл. Сначала вы должны подготовить папку в файловой системе локального диска, где должны храниться загруженные файлы. Например, /path/to/uploads (в Windows это будет на том же диске, где работает сервер). Обратите внимание, что вы абсолютно не должны хранить файлы в расширенной папке WAR, используя относительный путь или getRealPath() по причинам, указанным здесь. Загруженное изображение доступно только после обновления страницы.

Затем вам нужно автоматически сгенерировать имя файла. В противном случае, когда кто-то другой позже загрузит файл с таким же именем по совпадению, он будет перезаписан. Вы могли бы использовать Files#createTempFile() средство, чтобы получить автоматически сгенерированное имя файла.

Path folder = Paths.get("/path/to/uploads");
String filename = FilenameUtils.getBaseName(uploadedFile.getName()); 
String extension = FilenameUtils.getExtension(uploadedFile.getName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);

Путь к загрузке может быть при необходимости параметризован на основе одного из нескольких способов, показанных в этом разделе "Вопросы и ответы". Рекомендуемый способ сохранения загруженных файлов в приложении сервлета. FilenameUtils является частью Apache Commons IO, которую вы уже должны иметь в своем classpath, поскольку это зависимость от компонента загрузки файлов Tomahawk.

Наконец, просто передайте загруженный файл в этот файл (при условии Java 7):

try (InputStream input = uploadedFile.getInputStream()) {
    Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}

System.out.println("Uploaded file successfully saved in " + file);

Затем, чтобы загрузить его обратно, проще всего будет зарегистрироваться /path/to/uploads в качестве нового контекста веб-приложения или виртуального хоста, чтобы все эти файлы были доступны по URL. См. Также Загрузка изображений из папки webapps / webcontext / deploy с использованием тега или ;.

PrimeFaces использует два файловых декодера для загрузки содержимого p: fileupload

  1. NativeFileUploadDecoder
  2. CommonsFileUploadDecoder

NativeFileUploadDecoder является декодером загрузки по умолчанию, для него требуется контейнер сервлетов 3.0. Таким образом, если ваш контейнер сервлетов меньше 3, он не будет работать с вами. Также некоторые серверы приложений накладывают ограничения на использование содержимого, состоящего из нескольких частей.

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

CommonsFileUploadDecoder зависит от общей библиотеки Apache, поэтому вы должны поместить jar-файлы commons-fileupload и commons-io в ваш путь к классам, версия зависит от вашей версии простых лиц, но 1.3 и 2.2 соответственно работают для меня.

чтобы использовать CommonsFileUploadDecoder, вы должны использовать фильтр

<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

подождите, только фильтр не будет работать, потому что внутри фильтра он проверяет загрузчик, если он не предоставлен, и он обнаруживает, по крайней мере, JSF 2.2, поэтому он пропустит запрос к декодеру по умолчанию "Native", и тогда он не будет работать для вас.

чтобы заставить фильтр использовать общий декодер, вы должны поместить следующий контекстный параметр в ваш web.xml

<context-param>
<param-name>primefaces.UPLOADER</param-name>
   <param-value>commons</param-value>
</context-param>
Другие вопросы по тегам