Записать файл на диск, используя JSF 2.2 inputFile
Я пытаюсь загрузить файл изображения с помощью тега h:inputFile и записать его на диск.
Мой код JSF:
<h:form id="fileUploadForm" enctype='multipart/form-data' prependId="false">
<h:inputFile value="#{solicitacaoManagedBean.imagemCarregada}" />
<br />
<h:commandButton styleClass="btn btn-primary " value="Enviar" action="#{solicitacaoManagedBean.enviarImagem}" />
</h:form>
Мой ManagedBean:
@Named(value = "solicitacaoManagedBean")
@SessionScoped
@MultipartConfig(location = "/home/rogerio/tmp/")
public class SolicitacaoManagedBean implements Serializable {
private Part imagemCarregada;
(...)
public void enviarImagem() throws IOException {
try {
imagemCarregada.write("teste.jpg");
} catch (IOException ioe) {
System.out.println("Erro ao escrever: " + ioe.getLocalizedMessage());
}
}
}
Предположительно, метод write загружает элемент на диск, и IOException также не выбрасывается / перехватывается.
1 ответ
@javax.servlet.annotation.MultipartConfig
аннотация должна быть размещена на классе, реализующем HttpServlet
не на бэк-классе. По сути, эта аннотация должна быть размещена на FacesServlet
класс, который уже сделан с JSF 2.2.
Другими словами, @MultipartConfig
аннотация к классу компонента поддержки игнорируется и не имеет никакого эффекта, и файл фактически не сохраняется в location
Вы указали в аннотации. Вместо этого он был сохранен в пути относительно так называемого текущего рабочего каталога, который на данный момент является "текущей открытой папкой" java.exe
был выполнен. В случае веб-приложений Java это обычно двоичная папка сервера или около того. Вы можете отследить это, как показано ниже:
System.out.println(new File(".").getAbsolutePath());
Вы увидите ваш загруженный файл там.
Более того, даже если @MultipartConfig
аннотация сработала, location
Атрибут на самом деле не представляет место сохранения файла постоянной загрузки. Вместо этого он представляет временное место на диске для случая, когда размер загружаемого файла превышает доступное / настроенное пространство памяти. Вы никогда не должны хранить загруженные файлы постоянно в месте, указанном @MultipartConfig(location)
, Вы всегда должны получать содержимое файла через Part#getInputStream()
и запишите его в нужное постоянное место, предоставленное новым File
или же Path
представляющий абсолютный путь.
Избавиться от всего этого @MultipartConfig
аннотаций. Он не делает ничего полезного в классе бина. Просто получите содержимое файла Part#getInputStream()
и скопируйте его в нужный абсолютный путь:
try (InputStream input = imagemCarregada.getInputStream()) {
Files.copy(input, new File("/home/rogerio/tmp/teste.jpg").toPath());
}
Смотрите также
- Как сохранить загруженный файл в JSF
- Рекомендуемый способ сохранения загруженных файлов в приложении сервлета.
Независимо от конкретной проблемы, использование для этой цели bean-объекта сессионной области не является идеальным. Скорее используйте представление или запрос, ограниченный. Смотрите также Как правильно выбрать сферу применения бобов? И, используя prependId="false"
не рекомендуется для других целей, кроме форм входа в систему, связанных с каркасом входа в систему, который не поддерживает идентификатор с добавлением JSF в именах параметров запроса. Смотрите также UIForm с prependId="false" breaks