Exemplo com JSF 2.0

Na última sexta-feira, dia 30/01/2009, realizamos a primeira reunião de 2009 do JUGMS. Foi bem legal, contamos com mais de 100 pessoas. Nosso bate papo teve, além de conversarmos sobre os planos do JUGMS, dois assuntos bem interessantes. O Saulo falou um pouco sobre Análise e Projeto OO em Java, e eu sobre as novidades do JavaEE 6, parando um tempinho a mais na parte de JSF 2.0.

O tempo foi curto, e não deu pra explorar muito o exemplo, mas logo abaixo estou disponibilizando a apresentação (design show de bola :D) e o projeto de exemplo usando JSF 2. O exemplo foi feito usando Java 6 e tomcat 6.

Alguns pontos que eu procurei mostrar no exemplo foram:

API AJAX do JSF 2.0

No código do exemplo podemos ver trechos de código como este:

...
<h:commandButton value="Salvar" action="#{estadoBean.salvar}"
onclick="return facesAjaxRequest(this, event, {inputs: 'formEstado', render: 'formEstado:listaEstados'})"/>
...

onde eu criei essa função js chamada facesAjaxRequest que encapsula a simples chamada ajax do jsf 2 que seria assim:

jsf.ajax.request(element, event, options);

Essa funçao recebe o elemento que está disparando a ação (normalmente this), o evento e um mapa de parâmetros. Nesse mapa existem duas entradas: execute e render. No render, especificamos, separados pos espaços em branco, os clientIds dos componentes que serão renderizados novamente, e no execute passamos os valores a serem enviados ao server nessa requisição ajax.

No exemplo usei a função facesAjaxRequest para montar dinamicamente a lista que vai no parâmetro execute, por isso este parâmetro não aparece no primeiro exemplo mostrado. Com essa função, podemos ainda passar o id de qualquer elemento html pelo atributo inputs do mapa que todos os inputs e selects que estiverem abaixo desse elemento será enviado para o server. Na tela de cadastro de cidades fiz uma espécie de ajaxRegion usando essa forma bem simples.

Isso tudo porque o JSF 2 não tem algo tão fácil de usar como os componentes da biblioteca ajax4jsf. A idéia dessa biblioteca de ajax de jsf 2 não é deixar tudo mastigadinho, e sim prover uma infraestrutura básica uso padronizado de js nos componentes, eliminando ou diminuindo assim as incompatibilidades entre as bibliotecas de componentes disponíveis.

Update: Na época do Early Draft Review 2 só tínhamos a api js, mas logo depois saiu a tag estilo ajax4jsf e fiz um outro post sobre isso.

Para quem chegou a usar as funções js do Facelets 1.2, que nem chegou a ser continuado, e que eu mostrei num artigo que escrevi pra MundoJava há muito tempo, o funcionamento é quase o mesmo, só mudando praticamente o nome das funções js e a forma como os dados eram enviados ao server.

Facelets 2

Como já foi dito por aí, agora o JSF já vem por default com o Facelets 2 habilitado, não sendo necessário colocar nenhuma configuração para utilizálo. Inclusive no exemplo disponível para download, nem existe o arquivo faces-config.xml, pois fiz tudo por anotações e o Facelets já vem pronto pra uso. Mas é claro que ele continua sendo utilizado para as regras de navegação.

Criação de componentes com Facelets 2

Com facelets 2, a criação de componentes será algo mais “formal” do que fazemos com facelets hoje em dia. Isso graças a presença de uma definição do componente como esse:

...
<composite:interface name="beanSimples">
    <composite:attribute name="bean" required="true">
        <composite:attribute name="descricao" type="String" required="true"/>
    </composite:attribute>
</composite:interface>
 
<composite:implementation>
    Descrição: <h:inputText id="descricao" value="#{compositeComponent.attrs.bean.descricao}"/>
</composite:implementation>
 
...

O componete possui a interface e a implementação. Na interface podemos colocar os parâmetros que serão recebidos, como no exemplo onde eu preciso passar um objeto que eu chamei de “bean” e esse bean tem que ter um atributo do tipo String chamado descrição.

É possível ainda passar atributos que representam ações, o que não é possível hoje em dia. Além disso não é necessário nenhum arquivo para configurar o nosso componente customizado, tudo é feito através de convenção. Basta colocar o componente em uma pasta dentro do resources do jsf que ele já fica publicado e acessível por uma uri default. Mas se quisermos colocar uma uri específica é só indicar através de um arquivo de configuração.

SelectItems

Finalmente podemos usar o componente f:selectItems sem ter que criar uma lista ou array de SelectItem. Agora podemos usar diretamente nossos objetos do modelo como podemos fazer usando outros componentes de selectItems como o do Seam.

<h:selectOneMenu value="#{cidadeBean.cidade.estado}">
    <f:selectItems value="#{estadoBean.estados}" var="estado" itemLabel="#{estado.descricao}" itemValue="#{estado}"/>
</h:selectOneMenu>

Finalizando

O exemplo disponível é bem simples, mas procurei mostrar nele o uso de coisas simples, como as mencionadas acima, e também proporcionar para quem ainda não teve a disposição de começar a testar que já tenha um ponto de partida. Olhando o código fonte podemos ver funcionando também as novas tags para escrever css e js, e explorar a parte de localização de recursos, que é inclusive o que torna a criação de componentes tão simples.

Espero que esse post e os materiais relacionados sejam de utilidade, e caso você encontre algum erro no material disponível me avise comentando aqui ;)

30 thoughts on “Exemplo com JSF 2.0

  1. Parabéns Gilliard, excelente post!

    Interessante o suporte AJAX do JSF2.0, principalmente a opção de determinar quais os inputs [ou componente pai] será processado no lado servidor, isso com certeza facilitará a utilização de sub-formulários mais sofisticados nos conjuntos de componentes.

    Criar componentes com Facelets 2 está absurdamente mais simples do que fazemos hoje em dia, mesmo com Facelets “1”.

    Fico feliz com isso, pois o número de componentes [e consequentemente conjuntos de componentes] crescerá muito, sem falar que será até mais simples estender um componente e adapta-lo a nossas necessidades.

    Vou baixar seu projeto de exemplo e dá uma olhada mais de perto.

    Enfim, todos nós estamos ansiosos pelo JSF2.0 e principalmente com o upgrade dos conjuntos de componentes existentes, como o Richfaces.

    Parabéns pelo post e por ser uma grande referência de JSF2.0 no mercado nacional.

    Abraços.

  2. bom dia
    Gilliard, baixei esse projeto seu pra mim estudar e não está reconhecendo a anotação @PostConstruct oque pode ser? os jars são os que estao no projeto que vc disponibilizou e quanto aos demais anotações funcionam corretamente.

  3. Emerson, você está usando o Java6? Nele já tem essas anotações. Como disse no artigo eu usei o java6, mas acredito que com o 5 funcione da mesma forma, mas aí será preciso adicionar um jar com essas classes ou usar um servidor de aplicação que já as tenha, em vez do tomcat6 que eu usei. Mas acredito que baixar o jar e colocar no classpath seja melhor para testar (ficar subindo um servidor de aplicações como jboss é bem chatinho quando queremos testar rápido).

  4. valeu pela resposta!!
    eu estou usando o java 6 e o tomcat 6, estou tentando usar as mesmas configurações que vc mostrou usar para esse exemplo, já fiz um clean no projeto e nada mas vou continuar tentando aki vlw

  5. Gilliard consegui!!\o/
    eu não tinha adicionado o projeto dentro do tomcat e por isso não dava certo…
    o estranho é que sempre que crio projeto só adiciono ele na hora de executar e sempre funcionou, não sei pq esse foi assim!!
    mas do mesmo jeito abrigado, e vou continuar fuçando aki até conseguir ententer as diferenças do jsf 2.0 para o 1.2 vlw e parabéns pelo blog

  6. boa tarde!
    Gilliard vc já utilizou o @ViewScope?
    se já utilizou, poderia me dizer como funciona quando eu quero editar um objeto em uma página de listagem e tenho que mandar esse objeto para a edição atravéz da sessão?
    vlw

  7. bom dia,
    estava lendo seu blog de novo e tentando entender uma coisa:
    Como que será feita a navegação? baixei seu exemplo e está tudo ok, mas como que eu faço para encaminha uma página de listagem que possui um link editar para sua página de edição sendo que vc não criou o faces-config.xml para determinar o navigation-rule?

    obrigado.

  8. “Inclusive no exemplo disponível para download, nem existe o arquivo faces-config.xml, pois fiz tudo por anotações e o Facelets já vem pronto pra uso. Mas é claro que ele continua sendo utilizado para as regras de navegação.”

    Eu havia dito que não tinha colocado ele mas que continuava necessário. Só não usei pois preferi focar nas novidades para o artigo e o exemplo não ficarem muito grandes.

  9. Pingback: Gilliard Cordeiro » Blog Archive » <f:ajax> no JSF 2.0

  10. Olá Gilliard.
    Depois de muito pesquisar, enfim encontrei um ótimo local sobre JSF 2.0. Está de parabéns!
    Andei vendo seu código e percebi que na exibição de uma lista contida no bean (estadoBean.estados) você utilizou a tag “h:dataTable”. Você conhece algum jeito que eu possa criar um componente semelhante a este. Estou querendo fazer algo customizado, com divs, etc.
    Eu já tentei criar um “ui:composition”, mas não sei como iterar sobre a lista. O “c:forEach” não é renderizado pelo JSF aqui, mesmo com o jstl.jar no lib.

    E outra pergunta. Vccê está utilizando qual IDE pra escrever seus códigos. Estou com o Eclipse, mas ele não tem autocomplete para os arquivos xhtml. Tenho q editar num .jsp e copiar o código para o xhtml de volta.

    Obrigado e até mais!

  11. Obrigado André. Tente usar o ui:repeat do facelets para iterar os valores, em além do ui:composition tem o ui:component também. A diferença é que no segundo você tem um componente JSF representando seu componente feito em xhtml, podendo até fazer binding se você quiser.

    E eu uso o eclipse mesmo. Para ter mais opções você pode usar o JbossTools.

    Espero ter ajudado.

  12. Opa Gilliard,

    Parabens pelo blog. Fiz o download do projeto e funcionou tranquilo aqui, mas quero fazer modificações para dar uma estudada, a dúvida é, quando coloco o faces-config para configurar minhas navigation-rules tento testar e minhas páginas não aparecem de jeito nenhum. Sabe o que posso estar fazendo de errado?

  13. Olá Gilliard.
    Depois de muito pesquisar, enfim encontrei um ótimo local sobre JSF 2.0. Está de parabéns!
    Andei vendo seu código e percebi que na exibição de uma lista contida no bean (estadoBean.estados) você utilizou a tag "h:dataTable". Você conhece algum jeito que eu possa criar um componente semelhante a este. Estou querendo fazer algo customizado, com divs, etc.
    Eu já tentei criar um "ui:composition", mas não sei como iterar sobre a lista. O "c:forEach" não é renderizado pelo JSF aqui, mesmo com o jstl.jar no lib.

    E outra pergunta. Vccê está utilizando qual IDE pra escrever seus códigos. Estou com o Eclipse, mas ele não tem autocomplete para os arquivos xhtml. Tenho q editar num .jsp e copiar o código para o xhtml de volta.

    Obrigado e até mais!;. All the best!!

  14. Antes de mais nada obrigado.
    Você já tentou utilizar o ui:repeat? Mas independente disso o c:forEach deveria funcionar sim, mas o funcionamento nem sempre é como o esperado por ele rodar em um momento diferente do ui:repeat.
    Sobre IDE eu estou utilizando o Eclipse mesmo. Você pode usar o JBoss Tools para ter um bom suporte a autocomplete, mas ele ainda não está na versão final para eclipse galileo.

  15. Opa amigo,

    Interessante o post. Parabéns!
    Baixei o projeto e ao chamar a pagina hello.jsf e clicar no botão testar, tenho este erro: WARNING: /hello.xhtml @19,44 value=”#{helloBean.texto}”: Target Unreachable, identifier ‘helloBean’ resolved to null
    javax.el.PropertyNotFoundException: /hello.xhtml @19,44 value=”#{helloBean.texto}”: Target Unreachable, identifier ‘helloBean’ resolved to null

    Saberia dizer o que pode estar errado?

  16. @Gilliard Cordeiro
    Opa, obrigado pelo retorno…
    O erro é este mesmo… java 6 e tomcat 6.0.20…
    muito estranho…

    21/10/2009 16:55:59 com.sun.faces.lifecycle.ProcessValidationsPhase execute
    WARNING: /hello.xhtml @19,44 value=”#{helloBean.texto}”: Target Unreachable, identifier ‘helloBean’ resolved to null
    javax.el.PropertyNotFoundException: /hello.xhtml @19,44 value=”#{helloBean.texto}”: Target Unreachable, identifier ‘helloBean’ resolved to null
    at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:99)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:92)
    at javax.faces.component.UIInput.getConvertedValue(UIInput.java:969)
    at javax.faces.component.UIInput.validate(UIInput.java:895)
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1099)

  17. @Rafael, não consegui reproduzir esse erro. E como faz tempo que fiz esse exemplo, baixei de novo, importei pro eclipse e executei como você também deve ter feito. A diferença é que aqui funcionou.

    Minha esperança era uma mensagem de erro que respondesse porque o ‘helloBean’ não pôde ser criado :/

  18. opa, quanto aos SelectItems no exemplo você retornou um objeto itemValue=”#{estado}”, ainda tenho que fazer um converter para meu atributo receber um Estado??

  19. Rogério, você terá sim que ter um conversor. Inclusive no código fonte disponível tem esse conversor. Obviamente o que você pode fazer é criar um conversor genérico que trabalha co qualquer @Entity por exemplo.

  20. Estou com o mesmo erro relatado pelo Rafael. Tenho uma aplicação em JSF 2.0 que roda perfeitamente no GlassFishV3 mas no Tomcat chega a executar mas dá erro. Para tirar a prova, peguei o helloword exemplo do pacote JSF e ele também dá o mesmo erro. Pelo que percebi ele não entende a NÃO utilização do faces-config.xml, ou seja, não entende as anotações que indicam que a classe é um managedbean, resultando nesse tipo de mensagem:
    Target Unreachable, identifier ‘helloBean’ resolved to null.

    Sabe dizer quais são os .JARs envolvidos no reconhecimento dos managedbeans através das anotações?

  21. resolvido!!! reinstalei o tomcat 7.0 e joguei os dois arquivos do JSF e funcionou…

  22. @Gilliard Cordeiro

    boa tarde !
    bom esse topico é antigo mas estou com o mesmo problema do Emerson
    estou usando @ViewScope e quero editar um objeto em uma página de listagem e tenho que mandar esse objeto para a edição, eu consigo setar o objeto tudo certo mas não atualiza o objeto no banco tem como vc mandar para o meu email tb a soluação ?

  23. se eu quizer renderizar um form que esta em outra pagina como eu faco ?

  24. Pingback: Pós Reunião JUGMS 01/2009 – JUGMS

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>