Есть JSF страница (создание статьи) т.е. у меня получилось 2 формы (В сокращенном виде):
<h:form enctype="multipart/form-data">
<h:inputFile value="#{createPost.file}" >
</h:inputFile>
<h:commandButton action="${createPost.upload()}" value="Submit"/>
</h:form>
<h:form>
<h:inputText value="#{createPost.title}" id="title"
styleClass="form-control header-input"
p:placeholder="Заголовок должен четко отображать суть вашей статьи"
aria-describedby="header_addon">
<f:validator binding="${postValidator}"/>
<f:ajax event="blur" render="messageForTitle"/>
</h:inputText>
<pe:ckEditor id='editor' value="${createPost.content}" />
<h:commandButton action="#{createPost.makePost}" value="Отправить"
styleClass="send-article btn-lg btn-primary" />
</h:form>
Метод Bean отвественный за загрузку файла:
public void upload(){
if(file != null){
try(InputStream is = file.getInputStream()){
image = new byte[is.available()];
is.read(image);
}catch (IOException e){
e.printStackTrace();
}
}
}
Метод ответственный за создание поста:
public String makePost(){
String guardedContent = new XSSGuard().replaceScript(this.content);
new PostDatabaseFunctional().addPost(this.title, this.subtitle, this.image, guardedContent, this.tags);
return "feed";
}
Ситуация такая. При создании поста надо прикреплять название, картинку и контент.
В данный момент я загружаю картинку в inputFile, нажимаю загрузить, но метод upload даже не вызывается, зато при нажатии кнопки отправить внизу формы спокойно отправляются название и контент.
Если я помещаю верхнюю форму в нижнюю форму, то кнопка h:commandButton перестаёт работать, т.е. вообще не нажимается
Если я делаю только 1 форму, то при нажатии на кнопку отправить (h:commandButton) видно, что идет какой-то запрос, но опять же методы из бина не вызываются.
В чем может быть проблема, может как-то по другому можно загрузить файл?
переменная file имеет тип javax.servlet.http.Part
UPDATE 1: При такой записи формы внутри формы:
<h:form id="form1">
<h:form id="form2" enctype="multipart/form-data">
<h:inputFile value="${createPost.file}" autocomplete="on" maxlength="2048000" >
<f:ajax execute="@form" listener="${createPost.upload()}"/>
</h:inputFile>
</h:form>
<h:commandButton action="${createPost.makePost()}" value="Отправить" styleClass="send-article btn-lg btn-primary" />
</h:form>
В итоге получается всего одна форма, которая начинается с самой верхней h:form и заканчивается верхней /h:form, туда попадает только h:inputFile, соотвественно h:commandButton просто находится вне формы, поэтому и не реагирует ни на какие действия
После 2-х мучительных дней с этими файлами, я наконец нашёл решение(надолго запомню).
Вообщем моя проблема была в том, что у меня поверх всех фильтров стоял фильтр для переписки url адресов Pretty Faces, в случае с h:inputFile, он переписывал action формы с настоящего на новый, из за чего форма ничего не отсылала.
Как эта проблема решается, если у вас JSF 2.2 и h:inputFile:
1)Удалить Pretty Faces))
2)Если он вам нужен, то надо переписать атрибут action, внутри формы на настоящий с помощью Java Script(Я использовал библиотеку jQuery) пример:
<h:form styleClass="formneed" enctype="multipart/form-data">
<h:inputFile value="#{testBean.part}" >
<f:ajax listener="#{testBean.upload}"/>
</h:inputFile>
</h:form>
<h:outputScript library="js" name="jquery-3.3.1.min.js"/>
<h:outputScript>
$(document).ready(function () {
$(".formneed").attr("action", "/resources/pages/test.xhtml");
})
</h:outputScript>
Т.е. PrettyFaces в данном примере переписывает action="/test"(Должно быть action="/resources/pages/test.xhtml") и ничего не работает, мы должны своими ручками указать адрес настоящей страницы.
3)Мы можем использовать загрузку файлов от primefaces, но просто так она тоже работать не будет. Ибо поверх неё опять Pretty Faces filter. Для его работы необходимо скачать библиотеку primefaces с официального сайта, commons-io, commons-fileupload.
Все 3 библиотеки помещаем в /WEB-INF/lib, далее конфигурируем web.xml:
//Поверх всего в web.xml
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value>
</context-param>
<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>
<dispatcher>FORWARD</dispatcher>//Обязательно
</filter-mapping>
Теперь мы можем использовать загрузку от primefaces, вот пример:
<h:form enctype="multipart/form-data">
<p:fileUpload
fileUploadListener="#{testBean.loadFile}" update="messages"
auto="true" mode="advanced" multiple="false"
allowTypes="/(\.|\/)(png|jpe?g|gif)$/"/>
<p:growl id="messages" showDetail="true" />
</h:form>
(Не забываем во всех формах указывать enctype="multipart/form-data"), это нужно для пересылки файлов по http)
EDIT
Также забыл упомянуть, что проблема в primefaces может быть связана с подключением jQuery, он перестаёт работать, когда подключаешь посторонний jQuery, решением проблемы служит подключения собственного jQuery из primefaces:
<h:outputScript library="primefaces" name="jquery/jquery.js" />
Надеюсь это кому-то поможет и сэкономит их время.
Делаю реализацию игры Mastermind взял за основу алгоритм Кнута
Сделала авторизацию пользователя в javafx - приложенииУ меня есть 2 роли: ребенок и родитель
Как в scene builder сделать так, чтобы при развертывании окна любого размера равномерно растягивалась и сжималась картинка и ничего не сьезжало