JSF Mini Livro – Dicas, conceitos e boas práticas

Quando utilizar “action” ou “actionListener”

Toda requisição feita pelo usuário ao sistema pode-se entender como uma ação. Essa ação pode ter vários efeitos diferentes como alterar um registro no banco de dados, algum arquivo físico, uma navegação entre páginas, exibir uma informação, etc.

O JSF separa basicamente em dois modos esses tipos de ações: “com navegação” e “sem navegação”. As ações com navegação seriam as navegações em que direcionamos o usuário para outra tela como resultado final de uma ação a exemplo: “cadastrar uma cidade”, “entrar e sair do sistema”, etc. As ações sem navegação geralmente são chamadas Ajax ou chamadas de preparação para alteração do estado de objetos que estão na memória.

É preciso ter em mente que uma ação que gera uma navegação nem sempre irá levar o usuário para outra tela; no caso de um cadastro se o usuário não digitou todos os campos necessários ele continuará na tela e receberá uma mensagem de aviso notificando dos erros.

Ao utilizar os componentes “h:commandLink” e “h:commandButton”, os mais utilizados em ações, é possível ver a existência dos parâmetros “action” e “actionListener”. Podemos definir que “action” são as ações que utilizam navegações e “actionListener” como ação de requisição Ajax ou que irá modificar/preparar algum objeto sem navegação.

O modo correto de utilizar o “action” é apontar para um método de ManagedBean que em sua assinatura retorne uma String. A assinatura “public String cadastrar()” é uma assinatura válida de uma action. A String retornada irá indicar qual será o destino da ação solicitada pelo usuário. Após o retorno da String pelo método, o JSF tomará os seguintes passos:

  • Caso o valor retornado seja “null” o usuário permanecerá na mesma tela.
  • Caso o valor não tenha uma extensão válida, a extensão da view atual será utiliza. Ex.: Se na página “cadastro.xhtml” o método chamado retornar “paginaInicial” o JSF irá tratar como “paginaInicial.xhtml”.
  • Caso o valor retornado não comece com “/” o JSF irá tratar como “/paginaInicial.xhtml”.
  • O JSF irá verificar também regras de navegação incluídas no faces-config.xml
  • Qualquer valor retornado que não seja “null” fará com que o valor da view atual seja apagado. Imagine que o usuário está na página “cachorroCadastro.xhtml”, se o retorno do método for “null” o usuário continuará na página com os mesmos valores e uma nova navegação não será iniciada; caso o retorno seja a String “cachorroCadastro.xhtml” uma nova navegação será iniciada.

Já o “actionListener” requer uma assinatura diferente. Uma assinatura válida de um “actionListener” seria: “public void validarUsuario(javax.faces.event.ActionEventevent)”.

Em um botão é possível ter as duas chamadas ao mesmo tempo: “<h:commandButton action= “userMB.cadastrarUsuario” actionListener= “userMB.validarUsuario” />”. Repare que o click do botão chamará um método para validarUsuario e em outro é ação é para cadastrar o usuário.

Uma ação “actionListener” costuma ser utilizada muito nos componentes de view. Em um componente de paginação, seria utilizada uma ação de um actionListener para mudar as páginas que estão sendo exibidas sem executar uma navegação. Infelizmente pessoas acabam não utilizando esse recurso do modo correto e acabam por encontrar mais dificuldades do que necessário. Para fazer uma navegação a partir de uma ação “actionListener” teríamos que utilizar o método sendRedirect do HttpServletResponse; basta utilizar um método do tipo “action” para que essa navegação fosse realizada de modo simples e prático.

É aconselhável sempre usar as ações do tipo “action” em nos códigos JSF, caso a origem da ação não seja o código de um componente JSF ou uma chamada Ajax.

97 thoughts on “JSF Mini Livro – Dicas, conceitos e boas práticas

  1. Show de bola Esse Mini Livro em JSF.
    Mais um post excelente que contribui bastante com a galera que utiliza jsf.
    Vai ser de grande ajuda nos meus trabalho e estudos.
    Um Abraço

  2. Muito bom o post, seu blog é referencia em vários aspectos quando a conversa é JEE, tanto pela didática quanto pelo nivelde utilidade do conteudo exposto. Parabéns

  3. Opa!O post está muito bom! Podes colocar os códigos fontes do mesmo?
    Quando eu executo o projeto no eclipse, ele mostra a página sem o css e o facelets.
    Na pasta /lib estão os seguintes arquivos: jstl-1.2.jar e javax.faces-2.1.12.jar

    Um abraço

    • Rafael, bom dia.

      Esse post foi criado para a revista então as instruções foram criadas justamente para não precisar de fonte.

      Você está chamando a página pela url com “/faces/” ?

      Se sim, seu web.xml está maepado com o “/faces/” ? Quando fiz o tutorial o próprio eclipse criou o web.xml com essa configuração já ativa.

      Se não tiver mapeado lá, posso alterar e coloca-lo aqui. [=

      Aqui tem um exemplo pronto que você pode baixar que utilizar o facelets: http://uaihebert.com/?p=1414

      Obrigado pela visita.

      • Caro Hebert,
        Não estou chamando a a página pela url “/faces”. eu sempre marco “.jsf” no eclipse.

        O interessante é quando eu marco a opcao preview para ver a página ele mostra tudo certinho, na hora de rodar a aplicação, ele apenas mostra a página com texto plano.

        Me tire uma dúvida, se eu colocar no welcome-file-list que a página index é xhtml, o tomcat vai carregar normalmente ou tem que ser .html?

        Eu te pergunto, pois eu criei uma index.xhtml e o tomcat me deu o erro 404. Mesmo colocando no web.xml que poderia ser ela a página inicial.

        Tive que renomear para index.html para que a página fosse encontrada, mas mesmo assim, não carregou os estilos da página e nem o facelets.

        Abraço

        • Rafael, bom dia.

          Você precisa verificar o web.xml se *.jsf está presente.

          Se você realizar o download do código presente nesse post (http://uaihebert.com/?p=1414), você encontrará o modo correto que funciona.

          E para o facelets funcionar, a página precisa ser xhtml. [=

          Até a próxima

  4. Hebert boa tarde tudo bem?

    Viu eu nao entendi o que vc fez no @requestscoped , vi lá sobre o inputhidden
    mas como vc faz pra que a proxima pagina tenha o objeto carregado sendo que neste escopo ele zera.

    Parabens pelo mini livro , vc é o cara! your are the man!!

  5. Muito bom. Gostei muito.
    Podia gravar umas vídeos aulas pra gente e disponibilizar de alguma forma que ganhe também, algo como a devmedia, sei lah… xD

    • Anderson, boa tarde.

      Eu já pensei nisso. Estive inclusive estudando para fazer vídeo aulas, o problema foi tempo e máquina.

      O PC que eu tenho em minha casa que era capaz de fazer isso estragou. =/

      E o tempo que eu tinha disponível faleceu. Aí já viu né. =/

  6. Opa, ótimo post!

    Realmente bem completo, com vários detalhes que muita gente por aí não conhece, com certeza vai ajudar muita gente (inclusive eu, rs).

  7. Muito bom o conteúdo. Claro, prático e está me ajudando demais a aprender JSF.

    Eu vi uma abordagem para as bibliotecas que eu achei interessante. Vi num artigo do BalusC no StackOverflow. (http://stackoverflow.com/questions/11988415/what-is-the-jsf-resource-library-for-and-how-should-it-be-used)

    Nele o autor ao invés de criar as bibliotecas por tipo de recurso, ele cria por temas. No atributo library ele coloca o tema (ex: default) e no atributo name ele coloca o tipo de recurso antes do nome (ex: css/main.css)

    Os diretórios: ao invés de resources/css, resources/img etc., fica resources/default/css, resources/default/img etc. e resources/seutema1/css, resources/seutema1/img.

    Sucesso e um abraço.

    • Fernando, bom dia.

      Infelizmente não tenho.

      Levei dias escrevendo, formatando e editando o post. E depois levei mais tempo ainda para traduzir para o inglês.

      Não tenho tempo suficiente para passar tudo para PDF, pois tenho estudado muito esses dias.

      Obrigado pelo apoio.

  8. Boa meu caro ! Excelente post! Bom para me atualizar com o JSF ! Só uma pequena correção ortográfica no seu post, na página 15 temos o seguinte trecho:

    … valores e uma nova negação não será iniciada; caso o retorno seja a String “cachorroCadastro.xhtml” uma nova navegação será iniciada

    “negação” seria “navegação”, correto ? :)

    Grande abraço !

  9. Realmente Fantastico Parabéns. Vou já ler o de
    JPA Mini Livro – Primeiros passos e conceitos detalhados, muito obrigado pela contribuição.

    • David, bom dia.

      Sou o cara não, falta muito ainda! =D

      Apenas tenho exercitado a cuca pesadamente e postado aqui! Valeu pela atenção.

  10. Mt bom post amiguinho :D. Só ficou feio nesse post a frase: “Real Madrid, Campeão!”.
    Háááá >: ) agora ja sei tudo sobre JSF, ja da até para tirar a minha poderosa certificação e n escutar mais vc falando: “Querer estudar para certificação que é bom nada ne ? ” rsss

    Parabéns mais uma vez pelo post e sucesso !!!

    • Carutcho, boa tarde.

      Agradeço o apoio e pode ter certeza que após sua primeira certificação eu vou ficar te cutucando com: “Estudar para a segunda certificação nada né?!”.

      >= )

      Valeu pela visita mano! o_

  11. Parabéns pelo excelente artigo uaihebert.
    Você teria como detalhar mais um pouco sobre o escopo @ApplicationScoped?
    Tenho a seguinte situação: Há uma lista de Exercício(item 1, item 2, item N) acessível a vários usuários e cada item só pode ser respondido por uma pessoa(qualquer pessoa). O Problema: fazer com que quando uma pessoa abrir um item, por exemplo, os demais usuários não devem poder acessá-la simultaneamente. Poderia criar uma managedBean @ApplicationScoped com um ArrayList de item “em aberto”. Mas não sei como fazê-lo.
    Alguma ideia? Se possível uma implementação já feita por alguém…
    Agradeço!

    • Olá, tudo bem?

      No seu caso o ApplicationScoped não é ideal.

      O ApplicationScoped deve ser utilizado com informações que não são específicas a um usuário, ou seja, os dados lá não devem pertencer ao usuário A ou B.

      Imagine um combo de cidades que qualquer usuário do sistema poderia ver os dados.

      Espero ter ajudado [=

  12. A mensagem de erro retornada pela validação que é mostrada na tela antes mesmo de ser carregada a página não precisa de um execute?

      • Hebert, boa noite.

        A minha duvida era a seguinte, na parte de validação com o ajax em que o erro após uma validação aparece sem ter de recarregar a página não é preciso colocar o execute na tag ajax para as informações serem mandadas para o bean que possui a validação?

          • Opa, o,o vamos la professor, não houve resultado algum sem o execute e então coloquei o execute para levar as informações e ai funcionou com pois o action mesmo só funciona quando é submetido, (ACHO EU). Vlw ai velho to aprendendo bastante com seus posts, principalmente como utilizar os primefaces.

  13. Boa Noite!

    Tenho um template definido assim:

    Sistema

    Quando acesso qualquer p:menuitem ele recarrega toda página..
    Tem como carregar somente o layoutUnit do conteudo?? Via ajax sei la.
    Qualquer ajuda é bem vinda, links etc. Nos formularios também qualquer ação ele
    recarrega tudo.

    Felipe

    • Felipe, bom dia.

      Não vi sua mensagem antes pois ela entrou no spam. O.o

      Infelizmente aqui não é um bom local para colocar código, as tags morrem. =/

      Tente postar sua dúvida no GUJ, o povo lá é gente boa. [=

  14. Opa blza

    Cara tava usando o Netbeans.. ai mudei tudo blza. Ficou redondo até o fato de alguma coisa setada com acento dentro do java começou a ficar algo parecido com isso

    Mostrando 1 até 1 de 1 registros

    Essa mensagem é montada a partir de uma consulta. Pelo que notei só em códigos java esse problema.
    O que seria?

    • Felipe, boa noite.

      Você está com problema de enconding.

      Clique com botão direito em cima do projeto e vá em properties. Já na opção resources veja se está UTF-8, se não marque e reinicie o Eclipse.

      Veja c funciona. [=

  15. Testei aqui, na página index funciona perfeitamente.

    Mas sempre que eu tento usar o template em outro arquivo, dá erro (só mostra o texto, sem estilo nenhum). O que pode ser?

    • Rodrigo, boa tarde.

      Verifique se o caminho do template está correto, se seu arquivo do template contém h:head e h:body. Veja também se a URL que você está digitando no browser se o seu final está mapeado no web.xml.

  16. Primeiramente,

    Parabéns pelo o seu post, já adotei algumas práticas.

    O endereço do meu sistema aparece da seguinte forma:

    “www.endereco.com.br/sistema/faces/index.xhtml”

    Só que quando eu apago o /faces/ e abro o meu código fonte, ele exibe todos meus códigos, comentários (mesmo com aquela configuração no web.xml), chamada dos métodos…

    Tem alguma sugestão, dica ou não tem jeito?

  17. Olá uaihebert, me diz uma coisa, não tenho experiencia com JSF e estou ajudando um amigo com uma aplicação que ele desenvolveu.

    Ele hospedou em um host com tomcat e 128MB memória. Está tendo problemas com memória, poucos acessos e o servidor fica sem memória. Ele usa em pelo menos 2 MBeans a @SessionScoped. Poderia ser por isso o alto consumo de memória? Ou 128 mega é pouco para JSF 2?

    • Romarcio, bom dia.

      Realmente a quantidade de memória está baixa.

      Até consultei com amigos sobre essa quantidade e eles falaram a mesma coisa.

      Outro detalhe é que mesmo que se a aplicação tivesse um MB do tipo @SessionScoped, apenas esse cara já seria capaz de estourar a memória. [=

      Obrigado pela confiança, até mais. [=

      • Valeu pela ajuda Hebert. Tinha dúvida se o @SessionScoped poderia ser o vilão nesse caso, mas parece que não era o único.

        O cara tava usando JDBC puro com JNDI, e as conexões não eram fechadas mesmo chamando o close, e em um certo ponto a app travava. Como ele usou Spring Security, aproveitei e passei toda a parte de conexões para controle do Spring com JdbcTemplate e pelo menos testando em casa o problema foi resolvido.

        Mas existe 2 @SessionScoped na aplicação, vou alerta ele para que modifique isso.

        Obrigado!

        • Opa, por nada.

          Só para deixar claro, não creio que o problema seja SessionScoped, mas sim como ele é utilizado.

          Se ele for utilizado para conter listas, muitos valores em memória aí sim ele poderá atrapalhar a memória.

          Obrigado pela visita. =D

  18. Ainda não li tudo, mas pelo que eu já vi estou achando excelente.
    Você poderia fazer também um mini livro de JPA.

    • Marcelo, boa noite.

      Já existe aqui no blog um mini livro de JPA. Existe também um chamado Consultas e Dicas só com diversas funções de Pesquisa no JPA.

      Até mais.

  19. Hebert , tenho uma dúvida, para um caso de um método synchronized que efetua a persistência no banco neste caso a melhor forma de garantir que somente uma requisição será executada por vez é utilizando o @ApplicationScoped na classe onde o método se encontra? ou não há a necessidade disso!?

    Obrigado e parabéns pelo site.

  20. Parabéns pelo artigo Hebert.

    Eu estou com uma dúvida aqui, pelo que andei testando, no ViewScoped o MB não é eliminado da memória quando você fecha a página, só quando você faz um redirect dessa página. Isso é um comportamento que não tem como ser controlado?

    • Cleiton, boa tarde.

      Um jeito de controlar seria reduzindo o tamanho do tempo de sessão (3min por exemplo), e após fazer isso, você colocaria uma chamada Ajax de curtos períodos (2 em 2 min por exemplo) apenas para manter a sessão ativa.

      Espero ter ajudado, Obrigado pela visita.

  21. Hebert gostaria de parabenizá-lo pelo excelente trabalho que vc tem feito no Brasil, compartilhar o conhecimento e ajudar as pessoas é algo muito raro em um mundo tão egoísta como temos observado. Parabéns pela didática e o detalhamento passo a passo no seu material que ajuda todos os níves de estudantes. Qeu Deus abençoe muito a sua vida em todos os sentidos. Um abraço e parabéns pela iniciativa, tem me ajudado demais tb no trabalho.

    • Bruno, boa noite.

      Fico feliz que estou conseguindo ajudar.

      Valeu mesmo pelo apoio e pela força.

      Deus abençoe aí.

      Obrigado pela visita, e desculpe a demora em responder. Estive

    • João, boa tarde.

      Eu não tenho o material em PDF, dá muito trabalho já criar o post e seria tempo d+ em criar o PDF.

      Obrigado pela visita.

  22. Oi, estou começando agora com JSF e achar um material legal não é fácil. Mas sua iniciativa é ótima , ta me ajudando bastante. Obrigada.

    • Luciana, boa noite.

      Primeiro, me perde a demora em responder. Estou muito pegado no trabalho, para você ter idéia, estou te respondendo dele enquanto um deploy não termina.

      Obrigado pelo apoio, fico feliz em saber que estou ajudando. (:

  23. Muito bom!
    O que me deixou com dúvida foi esse arquivo, “faces-config.xml”. Meu projeto não conta com este arquivo. Seria o web.xml? OBS: Estou desenvolvendo em JSF 2.2

    Outra coisa, se eu for trabalhar com vários idiomas, terei vários arquivos um para cada idioma. Como ficaria o EL acessando diferentes arquivos?

    • Guerino, boa noite.

      Primeiro, me perde a demora em responder. Estou muito pegado no trabalho, para você ter idéia, estou te respondendo dele enquanto um deploy não termina.

      Esse arquivo não é mais obrigatório nas versões mais novas do JSF, por isso que seu projeto não tem.

      Quando você for usar com muitas linguagens sua EL continuará do mesmo modo. Você pode adicionar quantos arquivos quiser, isso nunca influenciará sua EL.

      Espero ter ajudado, obrigado pela visita.

Leave a Comment


× 6 = six