fev 09 2010

JavaServer Faces 2.0 na Prática – Parte 2

Category: JSF 2.0Edson Gonçalves @ 20:05

Olá, tudo bom? Como vão vocês?
Este artigo é o segundo de uma série ao qual vou ensiná-los a trabalhar com o JavaServer Faces 2.0.
Nesta segunda parte iremos conhecer e utilizar um Managed Beans.
Dúvidas e críticas são bem vindas.

Conhecendo o comportamento do  JavaServer Faces

Agora que já fizemos nossa primeira aplicação em JSF, é mais fácil de entender os serviços que o framework JSF oferece ao desenvolvedor.  Como pudemos ver, o framework JSF é responsável por interagir com o usuário (cliente) e fornece componentes para criar uma apresentação visual de uma aplicação Web, ou seja, o escopo de JSF é restringido à camada de apresentação. A persistência de banco de dados e outras conexões de back-end estão fora do escopo de JSF.

A arquitetura do JavaServer Faces, em um alto nível, se assemelha ao mostrado na Figura 1. Aplicações JSF utilizam como padrão a interceptação HTTP via Servlet Faces e produz HTML. Esta mesma arquitetura permite “plugar” novos elementos, gerando outras características, possibilitando criar páginas usando eventos, listeners e componentes como o seu irmão Java Swing.

A arquitetura JavaServer Faces

Figura 1. A arquitetura JavaServer Faces

A Figura 1 mostra a arquitetura rica e flexível existente no JSF, onde:

  • FacesServlet – é o servlet principal para a aplicação e, opcionalmente, você pode ter o arquivo de configuração faces-config.xml[1].
  • Renderers –  são os responsáveis por exibir um componente e traduzir uma entrada de valor realizada por um usuário em componente.
  • Páginas XHTML, JSP – o JavaServer Faces permite mais de um tipo de arquivo para renderizar seus componentes (PDL – Page Declaration Language[2]), como páginas JSP ou Facelets.
  • Converters – convertem o valor de um componente (como datas, moedas, porcentagem e outros) dando-lhes novos formatos.
  • Validators – responsáveis por validar a entrada ocorrida no componente pelo usuário.
  • Managed Bean – a lógica do negócio é gerenciada pelos managed beans, que controlam inclusive a navegação por entre páginas.
  • Ajax – Tanto o envio como o recebimento de dados podem ser feitos via Ajax, sem a necessidade de reload na página do usuário.

[1] Este arquivo só se tornou opcional na versão 2.0 ou superior.

[2] PDL herda a funcionalidade do núcleo de dois conhecidos projetos JSF: Facelets e JSFTemplates. Entre todos os outros recursos, permite criar novos componentes JSF de forma declarativa, sem a criação de um grupo de classes Java como era nas versões anteriores do JSF.

Compreendendo o comportamento da primeira página JSF criada

Assim como ocorre com outras bibliotecas de tags, o JavaServer Faces é configurado através da diretiva taglib, onde existem as bibliotecas que manipulam o HTML e a Core.

Para usar as tags HTML personalizadas que representam componentes JavaServer Faces, você precisa da diretiva taglib mostrada a seguir, geralmente posicionadas no topo de cada página JSP, como de costume no uso dessa diretiva.

<%@ taglib uri=”http://java.sun.com/jsf/html” prefix=”h”%>

No caso da utilização do Facelets, onde as páginas são XHTML’s, você terá a inclusão da tag personalizada HTML de JSF dessa forma:

<html … xmlns:h=”http://java.sun.com/jsf/html”>

Nota: Com a evolução, o desenvolvimento em JSF atualmente pode utilizar a versão com XHTML descartando a anterior, uma vez que se adéqua melhor ao modelo Web 2.0.

Dentre as tags JSF adicionadas na página, a tag <h:form />, representa um componente UIForm e cria um formulário para envio de dados pelo JSF. No HTML gerado, temos a tag <form/> para que o browser a compreenda.

A tag <h:outputText /> , representando um componente UIOutput que exibe valores, é a responsável pela geração do texto renderizado na página do usuário que, na grande maioria das vezes, é dinâmico. No atributo value você adicionou o texto diretamente, mas poderia adicionar a JSF EL (JavaServer Faces Expression Language), visto mais adiante, referente ao Bean criado, dando assim o retorno ao browser de um valor dinâmico produzido por uma entrada ou vindo do banco de dados.

A página no Browser

A página criada no aplicativo poderá ser aberta através do seguinte endereço também:

http://localhost:8080/TrabComJSF/faces/index.xhtml

Isso ocorre porque adicionamos a seguinte configuração no deployment descriptor (web.xml):

<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>

Os itens em destaque mostram que o Servlet FacesServlet, usado para renderizar os componentes JSF, é acionado quando temos “/faces/” antes do nome da página.

Adicionando um bean ao projeto

Na primeira página JSF que criou, você simplesmente adicionou o texto diretamente na tag HTML JSF  <h:outputText />.

Desta vez, você irá adicionar o conteúdo através de um Managed Bean, que nada mais é que uma classe JavaBean comum. A Listagem 1 mostra o conteúdo do Managed Bean que deverá ser feito:

Listagem 1 – A classe MeuManagedBean.java

package br.com.integrator;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name="meuManagedBean")
@RequestScoped
public class MeuManagedBean {

private String texto;

public String getTexto() {
return "Exemplo Simples";
}
}

A estrutura de diretórios com o Managed Bean

Sua estrutura de diretórios deverá ser similar ao mostrado na Figura 2, onde apresentamos a classe MeuManagedBean.java compilada:

Estrutura de diretórios do projeto TrabComJSF

Figura 2. Estrutura de diretórios do projeto TrabComJSF

Alterando a página do projeto

Vá até a página index.xhtml e altere a tag JSF  <h:outputText /> da seguinte forma:

<h:outputText value=”#{meuManagedBean.texto}” />

Ao alterar a tag <h:outputText/>, o atributo value recebeu agora os delimitadores #{…}. Estes delimitadores são indicações de expressão ao qual ligam o componente JSF ao Managed Bean e seu atributo get correspondente, neste caso.

No JavaServer Faces 2.0, usamos a anotação @ManagedBean, de javax.faces.bean.ManagedBean, para registrar a classe como sendo uma Managed Bean onde, através do atributo name, damos o nome que será acessível pelos componentes das páginas JSF. No caso, chamamos de meuManagedBean.

O conteúdo é exibido pelo método público getTexto(), responsável por enviar as informações do Managed Bean para a página JSF e exibi-las através da tag <h:outputText />. A Figura 3 mostra como funciona essa integração.

Um managed bean possui um escopo onde, no caso, está definido como por requisição[3]. Este escopo é definido na anotação @RequestScoped, de javax.faces.bean.RequestScoped.


[3] Isso indica que as informações transmitidas serão recebidas e permanecerão apenas na página ao qual foi requisitada. Se você navegar para outra página, estas informações se perdem.

Componente da página JSF lendo o Managed Bean

Figura 3. Componente da página JSF lendo o Managed Bean

Os Beans em JSF

Um bean em Java é uma classe que expõe atributos/propriedades e eventos em um ambiente como o JSF. Um atributo é nada mais que uma variável nomeada com um determinado tipo que pode ser lido ou escrito. No bean, existe a convenção de declarar tais atributos como sendo do tipo privado e expô-los através de métodos públicos que encapsulam seus valores com as iniciais: set e get que servem para atribuir um valor e para pegar este valor respectivamente.

Utilizando Getters e Setters em um Managed Bean

Para compreender melhor estas características, vamos modificar novamente o exemplo de modo que possamos enviar dados de um campo e recebê-los.

Rascunho da representação final do exemplo

Figura 4. Rascunho da representação final do exemplo

Altere a página index.xhtml como mostra o trecho a seguir:

<h:form>
<h:inputText id="texto" value="#{meuManagedBean.texto}" />
<br />
<h:commandButton value="Enviar Texto" action="enviar" />
<br />
<h3><h:outputText value="#{meuManagedBean.texto}" /></h3>
</h:form>

E altere o Managed Bean MeuManagedBean adicionando o método setText() e modificando o método getText() como mostra o trecho a seguir:

public String getTexto() {
return texto;
}
public void setTexto(String texto) {
this.texto = texto;
}

Pronto, basta rodar o exemplo que verá o resultado.

Submissão do texto da página para o Managed Bean e retornando

Figura 5. Submissão do texto da página para o Managed Bean e retornando

Na próxima Parte

Desta vez você utilizou mais dois componentes: <h:inputText /> e <h:commandButton />. O primeiro permite a inserção de dados. O atributo id é o nome atribuído ao componente e o value possui a expressão JSF que contém a ligação entre o componente e o atributo no Managed Bean. O segundo componente, o <h:commandButton />, teve o atributo value que representa o texto a ser exibido no componente e action, que chama um método no servidor e, se não houver método, recebe como valor uma string qualquer, que pode indicar navegação para outra página ou não.

Na Parte 3 de JavaServer Faces 2.0 na Prática teremos uma visão geral da arquitetura do framework, com pequenos exemplos funcionais em alguns dos seus aspectos.

Tags: , , , ,

20 Responses to “JavaServer Faces 2.0 na Prática – Parte 2”

  1. Rafael Brugnollo says:

    Parabéns pelos artigos! estão ótimos

    aguardo a parte 3 do JSF =]

  2. Edson Gonçalves says:

    @Rafael, siga adiante que está já postado a parte 3.

  3. Julio Pereira says:

    Cara, parabéns!! Muito bem explicado! A terceira parte foi a que mais aproveitei, mas as duas primeiras também estão super bem explicadas! Parabéns!

  4. Rogério says:

    Quando eu cliquei no botão de comando ocorreu o seguinte erro:
    Não foi possível encontrar um caso de navegação correspondente na ID de exibição ‘/index.xhtml’ para a ação ‘enviar’ com o resultado ‘enviar’

  5. Edson Gonçalves says:

    @Rogério,

    Somente olhando seu código para saber exatamente o que está ocorrendo.

  6. Conflito says:

    No meu exemplo também é gerada a mensagem:
    Não foi possível encontrar um caso de navegação correspondente na ID de exibição ‘/index.xhtml’ para a ação ‘enviar’ com o resultado ‘enviar’.

    Creio que esteja relacionada a alguma regra de navegação, que no caso do JSF 2.0 é implícito.
    Ainda não consegui resolver.
    Alguém tem idéia do que seja?

  7. Rodrigo M. Lopez says:

    Para tirar o erro “Não foi possível encontrar um caso de navegação correspondente na ID de exibição ‘/index.xhtml’ para a ação ‘enviar’ com o resultado ‘enviar’.”

    é só remover o action=”enviar” no h:commandButton

  8. Alexandre Ferreira says:

    @Edson Gonçalves
    @Rogério
    @Conflito

    Pessoal, é o seguinte esse Warning, – nao erro! -, acontece por vcs definirem seus web.xml como Developement

    javax.faces.PROJECT_STAGE
    Development

    No do Nosso amigo Edson nao aconteceu pq ele segui o exemplo da Parte 1 onde era definido “Production”

    javax.faces.PROJECT_STAGE
    Production

    É um Warning. Já dei o caminho, o nosso amigo Edson, com sua maravilhosa didatica explica melhor pra todos nos…

  9. Fernando says:

    No meu caso o eclipse helios não está fazendo o autocomplete no value dos componentes jsf.

  10. Edson Gonçalves says:

    @Fernando,

    Pode estar ocorrendo algum erro ou, dependendo do componente, ele pode não estar reconhecendo mesmo.

  11. André says:

    Estou com o mesmo problema do Rogério .. tenho um formulário que quando clico em salvar ele chama o método que realiza a operação, e retorna a mensagem :
    “Não foi possível encontrar um caso de navegação correspondente na ID de exibição…”

    Não indo para outra página….
    pensei em tirar o “action” como foi sugerido, mas dai como faço pra ele executar a operação e redirecionar a outra página ?

  12. André says:

    Comigo acontece o mesmo problema “Não foi possível encontrar um caso de navegação correspondente na ID de exibição” .. já alterei o PROJECT_STAGE para Production e os warnings continuam aparecendo…

    Outra coisa que acontece.. é que se clico num botão de submit de um form e este invoca um método que retorna uma String (que deveria ser a página de resultado) nada acontece… exemplo:

    Botão:

    Método:
    public String confirmaGravarAlteracao(){

    return “../sucesso.xhtml”;
    }

    O que pode estar causando este erro ?

  13. Hermann Miertschink says:

    Bom dia, estou com uma dúvida com relação ao JSF 2.0. O Tomcat7 tem compatibilidade total com ele?

  14. Edson Gonçalves says:

    @Hermann,

    Sim, é compatível como o Tomcat 6.

  15. Wellington Torrejais da Silva says:

    Obrigado, será de muita valia.

  16. Foster says:

    Parabéns Edson!
    Ficou bastante simples e eficiente a sua abordagem no framework.
    Esclareceu alguns detalhes que estavam faltando.
    Grato!

  17. Alan says:

    Muito bom seus posts de JSF 2.0
    Muito obrigado!!!

  18. João Guedes says:

    Olá Pessoal,

    Não estou conseguindo listar meus dados da tabela. Existe alguma coisa que precisa ser habilitado no JSF2?? Ja implementei 13 metodos e nada. Fico no aguardo….Não consigo listar

  19. Marcelo Cabral says:

    Ótimo artigo. Parabéns e Obrigado!

  20. Bruno - Tijolera says:

    Graças a este artigo que eu consegui fazer essa bagaça funcionar! = )

    Brigaduuu! Parabéns!

Leave a Reply