Атрибут командной кнопки JSF передан неправильно
-
23-09-2019 - |
Вопрос
У меня есть следующий код на странице jsf, поддерживаемый управляемым компонентом jsf
<h:dataTable value="#{poolBean.pools}" var="item">
<h:column>
<f:facet name="header">
<h:outputLabel value="Id"/>
</f:facet>
<h:outputText value="#{item.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputLabel value="Start Range"/>
</f:facet>
<h:inputText value="#{item.startRange}" required="true"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="End Range"/>
</f:facet>
<h:inputText value="#{item.endRange}" required="true"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Pool type"/>
</f:facet>
<h:selectOneMenu value="#{item.poolType}" required="true">
<f:selectItems value="#{poolBean.poolTypesMenu}"/>
</h:selectOneMenu>
</h:column>
<h:column>
<f:facet name="header"/>
<h:commandButton id="ModifyPool" actionListener="#{poolBean.updatePool}" image="img/update.gif" title="Modify Pool">
<f:attribute name="pool" value="#{item}"/>
</h:commandButton>
</h:column>
</h:dataTable>
Этот фрагмент кода предназначен для редактирования коллекции элементов.Каждая строка таблицы содержит кнопку "редактировать", которая отправляет измененные значения строки на сервер.У него есть сам элемент в качестве атрибута.Отправка выполняется путем вызова метода ActionListener в резервном управляемом компоненте.
Этот код корректно выполняется в Glassfish версии 2.1
Но когда сервер был обновлен до Glassfish версии 2.1.1, атрибут перестал передаваться корректно.Вместо передачи отредактированного элемента (когда мы меняем значения в строке таблицы, мы фактически изменяем поля базового объекта), исходный элемент отправляется на сервер, т. е.элемент, который ранее был предоставлен странице.Все изменения, которые были внесены на страницу, будут отменены.
Я попытался обновить версию jsf с 1.2_02 до 1.2_14 (мы используем jsf RI), но это не возымело никакого эффекта.
Может быть, кто-нибудь сталкивался с такой же проблемой?Любая помощь и предложения будут оценены по достоинству.
Решение
Стеклянные рыбки поставляются в комплекте с JSF. Glassfish v2.1.1 поставляется с Mojarra 1.2_13.На самом деле вам не нужно иметь свои собственные библиотеки JSF в /WEB-INF/lib
.Я не уверен, чем вызвана эта конкретная проблема, но для начала вам нужно убедиться, что у вас нет коллизий версий JSF в classpath.
Тем не менее, предпочтительным способом передачи свойств компонента в JSF 1.2 является использование f:setPropertyActionListener
.
<h:commandButton id="ModifyPool" actionListener="#{poolBean.updatePool}" image="img/update.gif" title="Modify Pool">
<f:setPropertyActionListener target="#{poolBean.pool}" value="#{item}"/>
</h:commandButton>
Обновить:Я кое-что припоминаю;эта проблема предполагает, что у вас все еще есть версия JSF 1.2, более старая, чем 1.2_05, в пути к классу.Обработка атрибутов компонента изменилась в соответствии с этой версией в пользу повышения производительности.В двух словах, если у вас есть jsf-api.jar
старше 1.2_05 в вашем пути к классу, в то время как есть jsf-impl.jar
1.2_05 или новее в вашем classpath, вы столкнетесь именно с этой проблемой.
Решение очевидно:очистите свой classpath, чтобы избавиться от более старой версии JSF.Пути, охватываемые classpath веб-приложения по умолчанию, находятся под каждым /WEB-INF/lib
, Appserver/lib
(что в случае со Стеклянной рыбой где -то в Appserver/domains/domainname/*
) и тот JRE/lib
и JRE/lib/ext
.Имейте в виду, что Стеклянная рыба javaee.jar
включает также библиотеки JSF, поэтому вам действительно нужно убедиться, что у вас нет этого JAR-файла (или любого другого JAR-файла, специфичного для сервера приложений) в вашем /WEB-INF/lib
или где-то еще.
Другие советы
Вы можете добавить Джбосс ЭЛ и написать:
#{poolBean.updatePool(item)}
Для этого вам не нужен весь Шов, он прекрасно работает с JSF RI.
Вероятно, это связано с тем, как JSF 1.2 реализует ActionListener .В JSF 1.1 и до недавних реализаций JSF 1.2 (Richfaces, Trinidad и т.д.) порядок был setPropertyActionListener (или Атрибут) -> ActionListener -> действие.В JSF 1.2 и теперь реализовано в Richfaces и Trinidad (не уверен насчет ICEfaces) порядок действий следующий: ActionListener -> setPropertyActionListener (или Attribute) -> action .Я знаю, что это тревожит и очень раздражает...Кто додумался до этого?Что они имели в виду?В любом случае, попробуйте использовать action вместо ActionListener и посмотрите, работает ли это.