Ответ 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.