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

Ajax com JSF 2.0

O Ajax é uma tecnologia que permite renderizar parte da tela do usuário sem a necessidade de atualizar toda a tela. Algumas vezes temos uma tela com muitas informações e ter que processar tudo novamente apenas por causa de um campo acaba sendo um incômodo para o usuário.

Na versão 1.2 do JSF o desenvolvedor precisava utilizar algum framework que implementasse a parte Ajax. Já a partir do JSF 2.0 o Ajax já está “nativo” e para utilizá-lo basta usar a biblioteca “f:ajax”.

Ao adicionar a tag f:ajax em um componente h:inputText o desenvolvedor estará adicionando um comportamento que será tratado pelo browser/servidor.  O exemplo mais fácil de Ajax seria fazer com que a cada tecla apertada em um input outro componente fosse atualizado.

Adicione a importação da tag na página xhtml:

xmlns:f="http://java.sun.com/jsf/core"

O código abaixo mostra como é simples a integração com Ajax (o meuBean teria apenas um get/set para a String nomeUsuario):

<h:inputText value="#{meuBean.nomeUsuario}">
	<f:ajax event="keyup" render="exibirNome" execute="@this" />
</h:inputText>

<h:outputText id="exibirNome" value="#{meuBean.nomeUsuario}" />

No exemplo acimaa cada vez que nosso usuário digitar um valor em seu teclado uma chamada será feita em nosso ManagedBean, o valor do atributo será alterado e terá seu valor atualizado no componente outputText.

O Ajax funciona diferente de um Request (GET/POST) pelo fato de que ele pode enviar ou não todo o form, e renderizar ou não componentes presentes na tela do usuário. Quando um HTTP Request é executado oriundo de uma página, todas as informações da página do usuário são enviadas, não é possível selecionar qual valor enviar; ao receber esse request o servidor irá processar todos os valores de todos os componentes. A facilidade do Ajax é a possibilidade de selecionar qual o valor que irá dentro da requisição e qual componente será atualizado na resposta.

No exemplo do código acima, foi indicado que o componente que será processado/executado será o inputText e o que será renderizado será o outputText. É possível ter um form com 15 inputTexts que seria possível selecionar quais inputs seriam enviados para serem processados. Do mesmo modo podemos selecionar qual componente será renderizado após o retorno da requisição Ajax.

Em cada requisição enviada via Ajax precisamos indicar um componente que será processado. No exemplo acima o componente foi passado através do “@this”. Esse valor indica que o componente que está com a tag f:ajax será processado na requisição, e como era um inputText, seu valor foi enviado nesse request. Os valores que são aceitos pelo execute e pelo render são: “@this”, “@form”,“@all”,“@none”. O valor default para o execute é “@this” e para render é “@none”.

Valores Execute render
@this Enviará o componente na requisição Ajax. Esse é o valor default. Renderizará o próprio componente que iniciou o request.
@form Todos os componentes presentes no form da tag “f:ajax” serão enviados na requisição. Renderizará todo o form em que a tag f:ajax, que originou a chamada ajax, se encontra.
@all Todos os componentes presentes na view serão enviados no request. Renderizará todos os componentes presente na view.
@none Nenhum componente será passado no request do ajax. Nenhum componente será renderizado após a chamada ajax. Esse é o valor default.

É necessário ter atenção quanto ao nome dos eventos. Não é utilizada a palavra “on” na frente da ação. Não utilizamos “onchange” quando o valor muda, mas apenas “change”.

A vantagem de utilizar Ajax com JSF 2.0 é a possibilidade renderizar qualquer tipo de componente. Componentes que exibirão mensagens, alertas, executarão validações nos campos, etc.

Alguns desenvolvedores utilizam o Javascript em validações mas não sabem que com o Ajax também é possível realizar tais validações. No código abaixo podemos ver a validação de um campo numérico que irá mostrar mensagem de erro sem a necessidade de um código Javascript.

<h:inputText id="numero" value="#{meuBean.numero}" >
	<f:convertNumber />
	<f:ajax event="keyup" render="@this mensagemNumero" />
</h:inputText>
<h:message for="numero" id="mensagemNumero" />

Caso o usuário digite um valor que não seja um número válido, uma mensagem de erro será exibida através do componente “h:message”. Note também que é possível passar mais de um componente na tag render; é possível também utilizar a mesma abordagem na tag execute.

A validação apresentada no código acima tem as seguintes vantagens:

  • Validações mais complexas podem ser feitas – caso existam validações que envolvam consultas em banco de dados, cálculos matemáticos e etc. Não é viável código complexo e/ou regras de negócio em Javascript.
  • Elimina códigos de Javascript – um dos grandes problemas com Javascript é que ele pode funcionar em um browser e em outro ter um determinado comportamento e não funcionar; com a validação via Ajax utilizando os componentes do JSF esse problema não ocorrerá.
  • Alguns campos já podem exibir avisos antes de submeter a página toda – realizando essa validação via Ajax seu usuário já poderá ver se tem algum valor errado. Um CEP digitado na máscara correta passaria pelo Javascript, mas poderia não ser encontrado no banco de dados.
  • Essa validação não pode ser burlada – validações porJavascript podem ser desligadas no browser ou até mesmo burladas. O usuário pode facilmente mudar uma configuração no browser e desabilitar a execução de qualquer Javascript. Plugins, como Firebug, permitem que um usuário altere o código Javascript da página que estiver sendo exibida. Após a desativação ou manipulação do Javascript qualquer validação que antes era realizada não irá realizar o trabalho desejado. A validação via Ajax é realizado pelo container e não pelo browser.

É preciso citar também que a validação do código acima tem a desvantagem de sempre disparar uma requisição Ajax no servidor. Se a validação for muito utilizada pode atrapalhar a boa performance do servidor. Nesse caso deve-se levar em consideração aplicar o Javascript e se passar dessa primeira validação utilizar a validação via 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