Bom dia pessoal. Esse é meu primeiro post, apesar de acompanhar a comunidade a algum tempo e sempre encontro a resolução dos meus problemas no estudo do Java Web, nesse momento, estou estudando JSF.
O problema é mais ou menos o seguinte: Eu tenho uma pagina xhtml que possui um datatable e em cada linha possui um commandLink que ,em seu action, chama um método de um Managed bean que executa algumas rotinas e devolve uma string com o caminho da próxima página. Até esse momento tudo funciona perfeitamente como esperado, o problema começa nessa segunda página xhtml!! Nela, existe um mesmo datatable, que é populado pelo MB que o redirecionou e em cada linha um commandLink com um action para outro método de outro Managed Bean, só que ao clicar neste commandLink dá um refresh na página e sequer é chamado o método no MB.
Abaixo está o código do datatable e o MB que deveria ser chamado:
<h3>Projetos</h3>
<h:dataTable var="projeto" value="#{grupoMBean.projetos}" id="projDataTable" styleClass="table table-hover mx-auto">
<h:column>
<f:facet name="header">Título</f:facet>
#{projeto.titulo}
</h:column>
<h:column>
<f:facet name="header">Autor</f:facet>
#{projeto.autor}
</h:column>
<h:column>
<f:facet name="header">Cap.Publicados</f:facet>
</h:column>
<h:column>
<f:facet name="header">Status</f:facet>
#{projeto.status}
</h:column>
<h:column>
<f:facet name="header">Ações</f:facet>
<h:form id="actionsInsideDatatable">
<h:commandLink value="DETALHES " action="#{projetoMBean.carregarDetalhesProjeto}">
<f:setPropertyActionListener value="#{projeto.id}" target="#{projetoMBean.idProjeto}" />
</h:commandLink>
</h:form>
</h:column>
</h:dataTable>
E o método do Managed bean que deveria ser chamado:
public String carregarDetalhesProjeto() {
Projeto auxProj = new Projeto();
auxProj.setId(idProjeto);
projeto = daoProjeto.pesquisar(auxProj);
return "admin/info_projetos";
}
Já pesquisei em outros tópicos com comportamentos semelhantes mas não obtive sucesso na resolução. Vale ressaltar que o segundo MB é anotado com @ManagedBean e o mesmo é reconhecido pelo eclipse no autocomplete na EL, bem como se eu copiar todo o h:form e colá-lo fora do datatable o método é chamado (e dispara um belo de um IllegalArgumentException - o que era de se esperar).
De antemão agradeço a todos os colegas pela atenção prestada.
Quando usava JSF, o mais comum era um form para toda a página. Dificilmente usava vários forms como vc está fazendo, pq o managedbean “se vira” para saber o que será executado, uma vez que a action não é informada no form, mas sim no botão (commandLink
no seu caso).
Não sei exatamente pq não funciona dessa forma, talvez seja a forma como o próprio JSF trata as requisições. Para tentar entender melhor, tu pode inspecionar o html gerado para ver o que ele está colocando no form que é renderizado em cada linha da tabela.
Sobre o seu estudo. Existe alguma razão específica para está estudando JSF? Pergunto isso, pq essa tecnologia é bem pouco utilizada hoje em dia, e geralmente as demandas que existem são de sistemas legados bem antigos. Deve ter quem use hoje em dia ainda, mas acredito que a demanda seja bem pouca.
Não se ofenda com minha observação em relação ao estudo, afinal, todo estudo é válido, porém, talvez, vc tenha um ganho maior estudando uma tecnologia onde a demanda é maior.
Olá Lucas, já tentei englobar o datatable no form e em toda página tbm (tendo os devidos cuidados para não ter um form dentro de outro), mesmo assim o comportamento era o mesmo.
Quanto aos estudos, se deve ao fato que onde trabalho possui muitos sistemas legados, usando JSF, JSP, Structs e por aí vai (só um pouco do sistema foi migrado para Spring), e sempre gostei de programação mas nunca tinha me aprofundado ou seguido por essa área (Sempre trabalhei na área de suporte e manutenção), e agora tive a oportunidade de entrar na equipe de desenvolvimento e existe demanda para dar manutenção a esses sistemas, então resolvi focar os estudos no JSF.
Mas sua observação é válida sim, não se preocupe, mas também é de mim mesmo querer aprender alguma coisa partindo dos primórdios, passando por cada evolução e aplicando isso na prática em algum projeto fictício, para no fim eu deixar eles apenas como um grande aprendizado e partidos para as tecnologias atuais, como Angular, React ou Vue (no caso de front-end).
1 curtida
Espetacular mano! Muito bom mesmo. Seu propósito é super válido mesmo! Nâo queimar etapas é muito importante para ser um bom profissional.
Sobre o problema, tente usar um h:commandButton só para testar.
1 curtida
Boa tarde Lucas, tinha realizado testes com o commandButton e não tinha obtido êxito, testei agora e o comportamento anormal continua. Acredito que só me resta trocar as versões das bibliotecas (tipo o jsf-api e o impl) e ainda persistindo o erro trocar de servidor, do Tomcat 9 para o 10 ou Wildfly, apesar que vou apanhar para fazer isso pois ví que houve mudanças de javax para jakarta.
Persistindo o comportamento, tentarei realizar o procedimento de outra forma.
Qual o escopo dos managedBeans usados?
Até o momento, todos estão com default (requestscope)
Pelo que me lembro, isso
<f:setPropertyActionListener value="#{projeto.id}" target="#{projetoMBean.idProjeto}" />
só funciona com managedBean
em escopo de sessão. Um outro teste que tu poderia fazer e chamar um método que não receba qualquer parâmetro da tela. Só para ver se ele chama.
O problema é que uma outra página com datatable similar, chama um MB que possui o mesmo escopo e funciona! é tanto que tbm fiz esse teste de criar um método simples pra ver se pelo menos chega no método, mas sem sucesso tanto no MB que a outra página chama sem problemas quanto no MB originalmente que deveria ser invocado.
Essa imagem acima eu enviei para um colega meu desenvolvedor que tbm não está conseguindo entender de não funcionar.
Vou verificar e darei um feedback em instantes…
Ah mano, eh msm. Qdo tu clica no botão, aparece alguma coisa no console da IDE não?
Nada. nenhum erro. Por isso não conseguia debuggar pq simplesmente passava direto
Suspeito que talvez o f:setPropertyActionListener
esteja causando algum problema. Pq, como disse, acho que essa tag só funciona com escopo de sessão ou view.
Acho q vou demorar um pouco para dar um feedback, depois de mudar o escorpo, estou recebendo TransientObjectException ao tentar carregar a primeira página. Vou passar o fim de semana refatorando o código para corrigir isso para depois aí sim eu testar o datatable.
1 curtida
Boa tarde Lucas. Não consegui mudar o escopo do Managed bean sem pipocar exception por todo lado. A solução momentânea que achei foi salvar os dados que eu precisava em uma variável de sessão a ser usada no Managed bean seguinte. Existe a solução para o meu caso usando @conversationScope
mas aí eu teria adicionar CDI ao projeto. Não que eu não queira usar, mas eu ainda não cheguei nessa. Quando chegar aí eu começo a fazer os ajustes no projeto para poder implementá-lo.
Mas que isso foi de um grande aprendizado, pois eu aprendi o porquê daquele comportamento estranho e provavelmente vou pensar nessa situação quando desenvolver algo semelhante novamente.
Obrigado, e até muito em breve.
1 curtida