O atributo de comando jsf é transferido incorretamente
-
23-09-2019 - |
Pergunta
Eu tenho o código seguinte na página JSF, apoiada pelo JSF gerenciado Bean
<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>
Este fragmento de código é dedicado à edição da coleção de itens. Cada linha da tabela contém o botão "Editar" que envia valores alterados da linha para o servidor. Ele tem o próprio item como um atributo. O envio é realizado chamando o método ActionListener no feijão gerenciado de apoio.
Este código é executado corretamente no Glassfish v 2.1
Mas quando o servidor foi atualizado para o Glassfish v 2.1.1, o atributo parou para ser passado corretamente. Em vez de aprovar o item editado (quando alteramos os valores na linha da tabela, estamos realmente alterando os campos de objeto subjacente), o item de origem é enviado ao servidor, ou seja, o item que foi fornecido anteriormente à página. Todas as alterações feitas na página são descartadas.
Tentei atualizar a versão JSF de 1.2_02 a 1.2_14 (estamos usando o JSF RI), mas não teve efeito.
Talvez alguém tenha encontrado o mesmo problema? Qualquer ajuda e sugestões serão apreciadas.
Solução
Glassfish navios com JSF agrupado. Glassfish v2.1.1 navios com mojarra 1.2_13. Você realmente não precisa ter seus próprios Libs JSF no /WEB-INF/lib
. Não tenho certeza de como esse problema específico é causado, mas, para começar, você precisa garantir que não tenha colisões de versão JSF no caminho de classe.
Dito isto, a maneira preferida JSF 1.2 de aprovar propriedades de feijão está usando 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>
Atualizar: Lembro -me de algo; Esse problema sugere que você ainda possui uma versão JSF 1.2 com mais de 1,2_05 no caminho de classe. O manuseio de atributos de componentes mudou de acordo com esta versão em favor dos aprimoramentos de desempenho. Em poucas palavras, se você tem um jsf-api.jar
de mais de 1,2_05 em seu caminho de classe, enquanto há um jsf-impl.jar
de 1.2_05 ou mais recente em seu caminho de classe, você terá exatamente esse problema.
A solução é óbvia: limpe seu caminho de classe para se livrar da versão JSF mais antiga. Caminhos cobertos pelo pathes de classe padrão do WebApp estão sob cada /WEB-INF/lib
, Appserver/lib
(que é em caso de peixe -glasta em algum lugar em Appserver/domains/domainname/*
) e o JRE/lib
e JRE/lib/ext
. Lembre -se de que o de Glassfish javaee.jar
Inclui bibliotecas JSF também, então você realmente precisa garantir que não tenha esse jar (ou qualquer outro arquivo jar específico do aplicativo) em seu /WEB-INF/lib
Ou em outro lugar.
Outras dicas
Você pode adicionar Jboss El e escreva:
#{poolBean.updatePool(item)}
Você não precisa de toda a costura para isso, funciona bem com o JSF RI.
Provavelmente tem a ver com a maneira como o JSF 1.2 implementa o ActionListener. No JSF 1.1 e até as implementações recentes do JSF 1.2 (Richfaces, Trinidad etc), o pedido foi setPropertyActionListener (ou atributo) -> ActionListener -> ação. No JSF 1.2 e agora implementado em Richfaces e Trinidad (não tenho certeza sobre os Faces Icefaces), a ordem é ActionListener -> setPropertyActionListener (ou atributo) -> ação. Eu sei que é perturbador e muito irritante ... quem pensou nisso? O que eles tinham em mente? De qualquer forma, tente usar uma ação em vez de um Listener Action e veja se funciona.