Как загрузить файл с помощью JSF 2.2 <h: inputFile>? Где сохраненный файл?

Я хотел бы иметь возможность загружать файлы в моем веб-приложении JSF2.2, поэтому я начал использовать новый компонент <h:inputFile>.

Вопрос только в том, как я могу указать местоположение, где файлы будут сохранены на сервере? Я хотел бы получить их как экземпляры java.io.File. Это должно быть реализовано в базе bean, но я не понимаю, как это сделать.

Ответы

Ответ 1

JSF не сохранит файл в любом предопределенном месте. Это будет просто предлагать вам загруженный файл в стиле javax.servlet.http.Part, который находится за кулисами, временно хранящимися в памяти сервера и/или временно на котором вы не должны беспокоиться.

Чтобы сохранить его в нужном месте, вам нужно получить контент Part#getInputStream(), а затем copy к Path, отображающему местоположение. Вы можете сделать это в методе (ajax) action (listenener) обычным способом. Вот пример, который делает это при прослушивании ajax во время события HTML DOM change:

<h:form enctype="multipart/form-data">
    <h:inputFile value="#{bean.file}">
        <f:ajax listener="#{bean.save}" />
    </h:inputFile>
</h:form>
private Part file; // +getter+setter

public void save() {
    try (InputStream input = file.getInputStream()) {
        Files.copy(input, new File(uploads, filename).toPath());
    }
    catch (IOException e) {
        // Show faces message?
    }
}

Папка uploads и filename полностью находятся под вашим контролем. Например. "/path/to/uploads" и Part#getSubmittedFileName() соответственно. Имейте в виду, что любой существующий файл будет перезаписан, вы можете использовать File#createTempFile(), чтобы автогенерировать имя файла.

Do не использовать Part#write(), как может предложить некоторый аргумент. Он будет в основном переименовывать файл во временном хранилище, как указано @MultipartConfig(location). Также используйте не ExternalContext#getRealPath(), чтобы сохранить загруженный файл в папке развертывания. Файл будет потерян, когда WAR перераспределяется по той простой причине, что файл не содержится в исходной WAR. Всегда сохраняйте его на абсолютном пути вне папки развертывания.

Для демонстрации в реальном времени проверьте последний элемент <o:graphicImage> демо на витрине OmniFaces.

См. также: