Как сохранить загруженный файл в 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
- NativeFileUploadDecoder
- 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>