corner imagecorner image
IDEPlatformPluginsDocs & SupportCommunityPartners

Introdução ao JavaServer Faces 2.0

O JavaServer Faces (JSF) é uma estrutura de interface de usuário (UI) para aplicativos da Web Java. Foi projetado para facilitar significativamente a trabalhosa tarefa de escrever e manter os aplicativos que são executados em um servidor de aplicativo Java e a processar as UIs de volta a um cliente de destino. O JSF oferece facilidade de uso das seguintes formas:

  • Facilita a construção de uma IU a partir de um conjunto de componentes de IU reutilizáveis
  • Simplifica a migração de dados do aplicativo para e a partir da IU
  • Ajuda a gerenciar o estado da IU nas solicitações do servidor
  • Oferece um modelo simples de conectar os eventos gerados pelo cliente ao código do aplicativo do lado do servidor
  • Permite personalizar os componentes de UI para que sejam facilmente construídos e reutilizados

Para uma descrição mais completa do framework JSF, consulte o Tutorial do Java EE, Capítulo 5: tecnologia JavaServer Faces.

Este tutorial demonstra como você pode aplicar o suporte do JSF 2.0 a um aplicativo da Web utilizando o NetBeans IDE. Primeiro, adicione o suporte da estrutura JSF 2.0 a um aplicativo da Web básico e, em seguida:

  • crie um Bean gerenciado por JSF para manipular os dados solicitados,
  • conecte o Bean gerenciado às páginas Web do aplicativo e
  • converta as páginas Web em arquivos de modelo Facelets.

O NetBeans IDE oferece, há muito tempo, suporte ao JavaServer Faces. Com a versão do JSF 2.0 e Java EE 6, o NetBeans IDE fornece suporte especial para JSF 2.0.Para mais informações, consulte Suporte ao JSF 2.0 no NetBeans IDE.

Conteúdo

O conteúdo desta página se aplica ao NetBeans IDE 6.8, 6.9. 7.0 e 7.1

Para concluir este tutorial, você precisa dos seguintes recursos e softwares.

Software ou recurso Versão necessária
NetBeans IDE conjunto 6.8, 6.9, 7.0, 7.1, Java EE
Java Development Kit (JDK) 6
Servidor GlassFish Código-fonte aberto edição 3.x
jsfDemo projeto de aplicativo da Web n/d

Observações:

  • O pacote NetBeans IDE Java também inclui o servidor GlassFish , um servidor compatível Java EE 6, que foi requisitado para este tutorial.
  • Para comparar seu projeto a uma solução que funciona, faça o download do projeto de amostra concluído.

Adicionando suporte JSF 2.0 a um aplicativo da Web

Comece abrindo o jsfDemo projeto do aplicativo da Web no IDE. Depois de abrir o projeto no IDE, você pode adicionar suporte à estrutura utilizando a janela Propriedades do projeto.

O IDE também permite criar novos projetos com o suporte JSF 2.0. Para obter mais informações, consulte Criando um novo projeto com o suporte JSF 2.0.

  1. Clique no botão Abrir projeto (botão Abrir projeto) na barra de ferramentas principal do IDE ou pressione Ctrl-Shift-O (&#8984-Shift-O no Mac).
  2. Na caixa de diálogo Abrir projeto, navegue até o local do seu computador onde você armazenou o projeto descompactado do tutorial. Selecione-o e clique em Abrir projeto para abri-lo no IDE.
  3. Execute o projeto para ver como ele aparece em um navegador. Clique com o botão direito do mouse no nó do projeto jsfDemo na janela Projetos e escolha Executar ou clique no botão Executar projeto (botão Executar projeto) na barra de ferramentas principal. O projeto é empacotado e implantado ao servidor GlassFish e o navegador é aberto para exibir a página de boas-vindas (index.xhtml).
    Captura de tela da página de boas-vindas no navegador
  4. Clique no botão Submeter. A página de resposta (response.xhtml) exibe o seguinte:
    Captura de tela da página de resposta no navegador
    Atualmente, as páginas de boas-vindas e resposta são estáticas e, juntamente com o arquivo stylesheet.css e a imagem duke.png, são apenas arquivos do aplicativo acessíveis de um navegador.
  5. Na janela Projetos (Ctrl-1; &#8984-1 no Mac), clique com o botão direito do mouse no nó do projeto e escolha Propriedades. A janela Propriedades do projeto é exibida.
  6. Selecione a categoria Frameworks e, em seguida, clique no botão Adicionar. Na caixa de diálogo exibida, selecione JavaServer Faces e clique em OK.
    Janela Propriedades do projeto: caixa de diálogo Adicionar uma estrutura
    Após selecionar JavaServer Faces, diversas opções de configuração se tornam disponíveis. Na aba Bibliotecas, você pode especificar como o projeto acessa as bibliotecas JSF 2.0. A opção padrão é utilizar as bibliotecas incluídas com o servidor (o servidor GlassFish). No entanto, o IDE também integra as bibliotecas JSF 2.0. (É possível selecionar a opção Bibliotecas registradas se desejar que seu projeto as utilize.)
    Configurações do JSF: aba Bibliotecas
  7. Clique na aba Configuração. É possível especificar como o servlet Faces é registrado no descritor de deployment do projeto. Também é possível indicar se deseja utilizar Facelets ou páginas JSP no projeto.
    Configurações do JSF: aba Configuração

    O NetBeans IDE 7.1 permite configurar facilmente seu projeto para usar vários conjuntos de componentes na guia Componentes. Para usar um conjunto de componentes, é preciso baixar as bibliotecas necessárias e usar o Gerenciador de Bibliotecas para criar uma nova biblioteca contendo as bibliotecas do conjunto de componentes.

    Configurações do JSF: aba Configuração
  8. Clique em OK para concluir as alterações e sair da janela Propriedades do projeto.

Depois de adicionar o suporte JSF ao seu projeto, o descritor de deployment web.xml do projeto é modificado para que se pareça com o código a seguir. (Alterações em negrito.)

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

Importante: se a entrada <welcome-file> não conter 'faces/', é recomendado adicionar manualmente. Isso assegura que a página de boas-vindas do projeto (index.xhtml) passe através do servlet Faces antes de ser exibida no navegador. Isso é necessário a fim de renderizar apropriadamente os componentes de biblioteca de marcação Facelets. Consulte Issue 182277 para mais informações.

O servlet Faces é registrado no projeto e a página de boas-vindas index.xhtml passa pelo servlet Faces quando é requisitada. Observe também que foi adicionada uma entrada no parâmetro de contexto PROJECT_STAGE. Ao definir esse parâmetro como 'Desenvolvimento', informações úteis são fornecidas quando o aplicativo é depurado. Consulte http://blogs.sun.com/rlubke/entry/jsf_2_0_new_feature2 para mais informações.

É possível localizar as bibliotecas JSF expandindo o nó Bibliotecas do projeto na janela Projetos. Se você estiver utilizando as bibliotecas padrão do servidor GlassFish, os arquivos jsf-api.jar e jsf-impl.jar são listados no nó do servidor GlassFish.

O suporte JSF 2.0 do IDE inclui principalmente vários assistentes específicos do JSF e a funcionalidade especial proporcionada pelo editor Facelets. Você explora esses capacidades funcionais nas etapas a seguir. Para mais informações, consulte Suporte JSF 2.0 no NetBeans IDE.


Criando um Bean gerenciado

É possível utilizar os beans gerenciados do JSF para processar dados do usuário e retê-los entre as requisições. Um bean gerenciado é um POJO (Plain Old Java Object) que pode ser utilizado para armazenar dados e é gerenciado pelo contêiner (por exemplo, o servidor GlassFish) utilizando a estrutura JSF.

Um POJO é essencialmente uma classe Java que contém um construtor público sem argumentos e está em conformidade com as convenções de nomeação do JavaBeans para suas propriedades.

Ao observar a página estática produzida ao executar o projeto, você necessita de um mecanismo que determine se o número inserido pelo usuário corresponde ao selecionado atualmente e retorna uma visualização apropriada para esse resultado. Utilize o assistente de bean gerenciado para criar um bean gerenciado para essa finalidade. As páginas Facelets que você criará na próxima seção precisarão acessar o número digitado pelo usuário e a resposta gerada. Para habilitar esta opção, adicione as propriedades userNumber e response ao Bean gerenciado.

Utilizando o assistente de bean gerenciado

  1. Na janela Projetos, clique com o botão direito do mouse no nó do projeto jsfDemo e selecione Novo > Bean gerenciado do JSF. (Se o bean gerenciado não estiver listado, escolha Outros. Em seguida, selecione a opção bean gerenciado do JSF na categoria JavaServer Faces. Clique em Avançar.)
  2. No assistente, insira o seguinte:
    • Nome da classe: UserNumberBean
    • Pacote: guessNumber
    • Nome: UserNumberBean
    • Escopo: Session
    Assistente de Bean gerenciado do JSF
  3. Clique em Terminar. A classe UserNumberBean é gerada e aberta no editor. Observe as anotações seguintes (mostradas em negrito):
    package guessNumber;
    
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    
    /**
     *
     * @author nbuser
     */
    @ManagedBean(name="UserNumberBean")
    @SessionScoped
    public class UserNumberBean {
    
        /** Creates a new instance of UserNumberBean */
        public UserNumberBean() {
        }
    
    }

    Como você está utilizando o JSF 2.0, pode declarar todos os componentes específicos do JSF utilizando as anotações. Nas versões anteriores, era necessário declará-los no arquivo de configuração Faces (faces-config.xml).

    Para visualizar o Javadoc para todas as anotações JSF 2.0, consulte Especificações de anotação de bean Faces gerenciadas.

Criando um construtor

O construtor UserNumberBean deve gerar um número aleatório entre 0 e 10 e armazená-lo em uma variável de instância. Isso forma parcialmente a lógica corporativa do aplicativo.

  1. Defina um construtor para a classe UserNumberBean. Insira o código seguinte (alterações exibidas em negrito).
    public class UserNumberBean {
    
        Integer randomInt;
    
        /** Creates a new instance of UserNumberBean */
        public UserNumberBean() {
            Random randomGR = new Random();
            randomInt = new Integer(randomGR.nextInt(10));
            System.out.println("Duke's number: " + randomInt);
        }
    
    }
    O código acima gera um número aleatório entre 0 e 10, e o número é exibido no registro do servidor.
  2. Corrigir importações. Para isso, clique no ícone da dica (ícone da dica) exibido na margem esquerda do editor, em seguida, escolha a opção para importar java.util.Random para a classe.
  3. Execute o projeto novamente (clique no botão Executar projeto (botão Executar projeto) ou pressione F6, fn-F6 no Mac). Quando você executa seu projeto, o arquivo de registro do servidor se abre na janela Saída.
    Registro do servidor na janela Saída
  4. Observe que você não vê o "número do Duke: " listado na saída (como deveria ser indicado no construtor). Um objeto UserNumberBean não foi criado porque o JSF utiliza instanciação lenta por padrão. Isto é, os Beans em determinados escopos são criados e inicializados somente quando o aplicativo precisa deles.

    O Javadoc da anotação@ManagedBean afirma:

    Se o valor do atributo eager() for verdadeiro e o valor de managed-bean-scope for "aplicativo", o tempo de execução deve instanciar essa classe quando o aplicativo iniciar. Essa instanciação e armazenamento da instância devem ocorrer antes que as requisições sejam processadas. Se eager não estiver especificado ou for false, ou se o managed-bean-scope for diferente de "application", ocorre a instanciação "lenta" padrão e o armazenamento com escopo do Bean gerenciado.
  5. Como UserNumberBean é escopo de sessão, implementou-se a interface Serializable.
    @ManagedBean(name = "UserNumberBean")
    @SessionScoped
    public class UserNumberBean implements Serializable {
    Use o ícone da dica (ícone da dica) para importar java.io.Serializable para a classe.

Adicionando propriedades

As páginas Facelets que você criará na próxima seção precisarão acessar o número digitado pelo usuário e a resposta gerada. Para facilitar essa tarefa, adicione as propriedades userNumber e response à classe.

  1. Comece declarando um Integer denominado userNumber.
    @ManagedBean(name="UserNumberBean")
    @SessionScoped
    public class UserNumberBean implements Serializable {
    
        Integer randomInt;
        Integer userNumber;
  2. Clique com o botão direito do mouse no editor e escolha Inserir código (Alt-Insert; Ctrl-I no Mac). Escolha Getter e setter.
    Janela pop-up Gerar código
  3. Selecione a opção userNumber : Integer.
    Caixa de diálogo Gerar getters e setters
    Clique em Gerar. Observe que os métodos getUserNumber() e setUserNumber(Integer userNumber) são adicionados à classe.
  4. Crie uma propriedade resposta. Declare uma String denominada response.
    @ManagedBean(name="UserNumberBean")
    @SessionScoped
    public class UserNumberBean implements Serializable {
    
        Integer randomInt;
        Integer userNumber;
        String response;
  5. Crie um método getter para resposta. (Este aplicativo não precisará de um setter.) Você poderia utilizar a janela pop-up Gerar código do IDE mostrada acima, na etapa 2, para gerar o código do modelo. Neste tutorial, no entanto, basta colar o método abaixo na classe.
    public String getResponse() {
        if ((userNumber != null) && (userNumber.compareTo(randomInt) == 0)) {
    
            //invalidate user session
            FacesContext context = FacesContext.getCurrentInstance();
            HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
            session.invalidate();
    
            return "Yay! You got it!";
        } else {
    
            return "<p>Sorry, " + userNumber + " isn't it.</p>"
                    + "<p>Guess again...</p>";
        }
    }
    O método acima realiza duas funções:
    1. Testa se o número inserido pelo usuário (userNumber) é igual ao número aleatório gerado para a sessão (randomInt) e retorna uma resposta String apropriada.
    2. Isso invalida a sessão do usuário se o usuário adivinha o número correto (isto é, se userNumber é igual a randomInt). Isso é necessário para que um novo número seja gerado caso o usuário queira jogar novamente.
  6. Clique com o botão direito do mouse no editor e escolha Corrigir importações (Alt-Shift-I; &#8984-Shift-I no Mac). As instruções de importação são criadas automaticamente para:
    • javax.servlet.http.HttpSession
    • javax.faces.context.FacesContext

    É possível pressionar Ctrl-Espaço nos itens do editor para chamar as sugestões do autocompletar de código e o suporte da documentação. Pressione Ctrl-Espaço no FacesContext para visualizar a descrição da classe do Javadoc.


    Janela pop-up da documentação
    Clique no ícone do navegador Web (Ícone do navegador Web ) na janela da documentação para abrir o Javadoc em um navegador Web externo.

Conectando Beans gerenciados às páginas

Uma das principais finalidades do JSF é remover a necessidade de escrever códigos clichês para gerenciar os POJOs e suas interações com as visualizações do aplicativo. Você viu um exemplo disso na seção anterior, no qual o JSF instanciou um objeto UserNumberBean quando o aplicativo foi executado. Este conceito é denominado Inversão de Controle (IoC), que permite que o contêiner se responsabilize pelo gerenciamento de partes do aplicativo que, do contrário, exigiriam que o desenvolvedor escrevesse repetitivos códigos.

Na seção anterior, você criou um bean gerenciado que gera um número aleatório entre 0 e 10. Também criou duas propriedades, userNumber e response, que representam o número inserido pelo usuário e a resposta a uma tentativa do usuário, respectivamente.

Nesta seção, você explora como é possível utilizar UserNumberBean e suas propriedades em páginas da Web. O JSF permite que você faça isso utilizando a sua linguagem de expressão (EL). A linguagem de expressão é utilizada para vincular os valores da propriedade aos componentes da UI do JSF contidos nas páginas da Web do seu aplicativo. Esta seção demonstra como você pode tirar vantagem do recurso de navegação implícita do JSF 2.0 para navegar entre o índice e as páginas de resposta.

O IDE oferece suporte a esta tarefa através dos recursos auto-completar código e documentação, que podem ser chamados pressionando Ctrl-Espaço nos itens no editor.

Comece fazendo alterações em index.xhtml e, em seguida, em response.xhtml. Em ambas as páginas, substitua os elementos do formulário HTML por seus equivalente JSF, conforme estão definidos na biblioteca de marcações HTML JSF. Em seguida, utilize a linguagem de expressão JSF para vincular os valores da propriedade aos componentes da UI selecionada.

index.xhtml

  1. Abra a página index.xhtml no editor. Clique duas vezes no nó index.xhtml da janela Projetos, ou pressione Alt-Shift-O para utilizar a caixa de diálogo Ir para arquivo.

    As páginas índice e resposta já contêm os componentes de UI do JSF necessários para este exercício. Basta eliminar os comentários existentes e fazer comentários nos elementos HTML que estão sendo usados no momento.
  2. Comente no elemento de formulário HTML. Para isso, realce o elemento de formulário HTML, como na imagem abaixo, e pressione Ctrl-/ (&#8984-/ no Mac).

    Nota: para realçar, clique e arraste o mouse no editor ou, utilizando o teclado, mantenha Shift pressionado e pressione as teclas de seta.
    Código realçado no editor

    Utilize Ctrl-/ (&#8984-/ no Mac) para alternar entre comentários no editor. É possível aplicar esse atalho de teclado em outros tipos de arquivos, como Java e CSS.

  3. Elimine o comentário do componente do formulário HTML JSF. Realce o componente, conforme a imagem abaixo, e pressione Ctrl-/ (&#8984-/ no Mac).
    Código realçado no editor
    Após eliminar o comentário do componente de formulário HTML JSF, o editor indica que as marcas <h:form>, <h:inputText> e <h:commandButton> não foram declaradas.
    Mensagem de erro do editor
  4. Para declarar esses componentes, utilize o autocompletar de código do IDE para adicionar o namespace de biblioteca de marcação à marcação <html> da página. Coloque o cursor em qualquer uma das marcações não declaradas e pressione Ctrl-Espaço. As sugestões do auto-completar código e o suporte da documentação são exibidos.
    Sugestões do auto-completar código e janela pop-up da documentação
    Clique em Inserir. (Se houver várias opções, certifique-se de selecionar a marca exibida no editor antes de clicar em Indicar.) O namespace da biblioteca de marcas HTML JSF é adicionado à marca <html> (mostrado em negrito abaixo), e os indicadores de erro desaparecem.
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html">
  5. Utilize a linguagem de expressão JSF para vincular a propriedade, de UserNumberBean, userNumber ao componente inputText. O atributo valor pode ser utilizado para especificar o valor atual do componente processado. Digite o código exibido em negrito abaixo.
    <h:form>
        <h:inputText size="2" maxlength="2" value="#{UserNumberBean.userNumber}" />
    A linguagem de expressão JSF utiliza a sintaxe #{}. Dentro desses delimitadores, você especifica o nome do bean gerenciado e a propriedade do Bean que deseja aplicar, separado por um ponto (.). Agora, quando os dados do formulário forem enviados ao servidor, o valor será salvo automaticamente na propriedade userNumber utilizando o setter da propriedade (setUserNumber()). Da mesma forma, quando a página for requisitada e um valor para userNumber já tiver sido definido, o valor será exibido automaticamente no componente inputText processado. Para mais informações, consulte o Tutorial do Java EE 6: utilizando a EL unificada para fazer referência a beans de apoio.
  6. Especifique o destino da requisição chamada ao clicar no botão do formulário. Na versão HTML do formulário, você era capaz de fazer isso utilizando o <form> do atributo ação da marcação. Com o JSF, é possível utilizar, do commandButton, o atributo ação. Além disso, devido ao recurso de navegação implícita do JSF 2.0, basta especificar apenas o nome do arquivo de destino, sem a extensão do arquivo.

    Digite o código exibido em negrito abaixo.

    <h:form>
        <h:inputText size="2" maxlength="2" value="#{UserNumberBean.userNumber}" />
        <h:commandButton id="submit" value="submit" action="response" />
    </h:form>

    O tempo de execução do JSF procura um arquivo denominado resposta. Ele supõe que a extensão do arquivo é a mesma que a extensão utilizada pelo arquivo a partir do qual se originou a requisição (index.xhtml) e procura o arquivo response.xhtml no mesmo diretório do arquivo de origem (por exemplo, webroot).

    Nota: o JSF 2.0 possui o objetivo de tornar as tarefas dos desenvolvedores muito mais fácil. Se estivesse utilizando o JSF 1.2 para este projeto, você teria que declarar uma regra de navegação em um arquivo de configuração Faces que se assemelharia ao seguinte:

    <navigation-rule>
        <from-view-id>/index.xhtml</from-view-id>
    
        <navigation-case>
            <from-outcome>response</from-outcome>
            <to-view-id>/response.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>

    As etapas de 7 a 12 são opcionais. Se quiser construir o projeto rapidamente, passe para response.xhtml.

  7. Verifique se a expressão EL acima de fato chama o método setUserNumber() quando a requisição é processada. Para isso, utilize o depurador Java do IDE.

    Alterne para a classe UserNumberBean (Pressione Ctrl-Tabulação e escolha o arquivo na lista.) Defina um ponto de interrupção na assinatura do método setUserNumber(). É possível fazer isso clicando na margem esquerda. É exibido um ícone vermelho, indicando que foi definido um ponto de interrupção do método.

    Ponto de interrupção na margem esquerda do editor
  8. Clique no botão Depurar projeto (botão Depurar projeto) na barra de ferramentas principal do IDE. A sessão de depuração se inicia e a página de boas-vindas do projeto se abre no navegador.

    Nota: se uma caixa de diálogo Depurar projeto é exiba, selecione a opção 'Server side Java' padrão e clique em Depurar.

  9. No navegador, insira um número no formulário e clique no botão Submeter.
  10. Volte ao IDE e examine a classe UserNumberBean. O depurador é interrompido no método setUserNumber().
    Editor exibindo o depurador interrompido
  11. Abra a janela Variáveis do depurador (Escolha Janela > Depurando > Variáveis ou pressione Ctrl-Shift-1). Você vê os valores das variáveis no ponto em que o depurador foi interrompido.
    Janela Variáveis

    Na imagem acima, o valor '4' é fornecido à variável userNumber na assinatura setUserNumber(). (O número 4 foi inserido no formulário.) 'isso' se refere ao objeto UserNumberBean criado para a sessão do usuário. Abaixo dele, você vê que o valor da propriedade userNumber é atualmente null.

  12. Na barra de ferramentas do Depurador, clique no botão Passar dentro (botão Passar dentro). O depurador executa a linha na qual ele está atualmente suspenso. A janela Variáveis se atualiza, indicando as alterações na execução.
    Janela Variáveis

    A propriedade userNumber está agora definida com o valor inserido no formulário.

response.xhtml

  1. Abra a página response.xhtml no editor. Clique duas vezes no nó response.xhtml da janela Projetos ou pressione Alt-Shift-O para utilizar a caixa de diálogo Ir para arquivo.
  2. Comente no elemento do formulário HTML. Realce as marcas HTML <form> de abertura e fechamento e o código entre elas, depois pressione Ctrl-/ (&#8984-/ no Mac).

    Nota: para realçar, clique e arraste o mouse no editor ou, utilizando o teclado, mantenha Shift pressionado e pressione as teclas de seta.

  3. Elimine o comentário do componente do formulário HTML JSF. Realce as marcas <h:form> de abertura e fechamento e o código entre elas, depois pressione Ctrl-/ (&#8984-/ no Mac).

    Neste estágio, o código entre as marcações <body> tem a seguinte aparência:

    <body>
        <div id="mainContainer">
    
            <div id="left" class="subContainer greyBox">
    
                <h4>[ response here ]</h4>
    
                <!--<form action="index.xhtml">
    
                    <input type="submit" id="backButton" value="Back"/>
    
                </form>-->
    
                <h:form>
    
                    <h:commandButton id="backButton" value="Back" />
    
                </h:form>
    
            </div>
    
            <div id="right" class="subContainer">
    
                <img src="duke.png" alt="Duke waving" />
                 <!--<h:graphicImage url="/duke.png" alt="Duke waving" />-->
    
            </div>
        </div>
    </body>

    Após eliminar o comentário do componente de formulário HTML JSF, o editor indica que as marcas <h:form> e <h:commandButton> não foram declaradas.

  4. Para declarar esses componentes, utilize o autocompletar de código do IDE para adicionar o namespace de biblioteca de marcação à marcação <html> da página.

    Utilize o suporte autocompletar de código do editor para adicionar os namespaces JSF necessários ao arquivo. Ao selecionar uma marcação JSF ou Facelets através do autocompletar de código, o namespace necessário é automaticamente adicionado ao elemento raiz do documento. Para mais informações, consulte Suporte JSF 2.0 no NetBeans IDE.

    Coloque o cursor em qualquer uma das marcações não declaradas e pressione Ctrl-Espaço. As sugestões do auto-completar código e o suporte da documentação são exibidos.

    Sugestões do auto-completar código e janela pop-up da documentação

    Clique em Inserir. (Se houver várias opções, certifique-se de selecionar a marca exibida no editor antes de clicar em Indicar.) O namespace da biblioteca de marcas HTML JSF é adicionado à marca <html> (mostrado em negrito abaixo), e os indicadores de erro desaparecem.

    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html">
  5. Especifique o destino da requisição que é chamada quando o usuário clica no botão do formulário. Você deseja definir o botão para que quando um usuário clique nele, tal usuário retorne à página de índice. Para isso, utilize, do commandButton, o atributo ação. Digite o código exibido em negrito.
    <h:form>
    
        <h:commandButton id="backButton" value="Back" action="index" />
    
    </h:form>

    Nota: ao digitar action="index", você está confiando no recurso de navegação implícita do JSF. Quando um usuário clica no botão do formulário, o tempo de execução do JSF procura um arquivo denominado índice. Ele supõe que a extensão do arquivo é a mesma que a extensão utilizada pelo arquivo a partir do qual se originou a requisição (resposta.xhtml) e procura o arquivo index.xhtml no mesmo diretório do arquivo de origem (por exemplo, webroot).

  6. Substitua o texto estático "[ response here ]" pelo valor da propriedade, de UserNumberBean, resposta. Para isso, utilize a linguagem de expressão JSF. Insira o texto seguinte (em negrito).
    <div id="left" class="subContainer greyBox">
    
        <h4><h:outputText value="#{UserNumberBean.response}"/></h4>
  7. Execute o projeto (clique no botão Executar projeto (botão Executar projeto) ou pressione F6; fn-F6 no Mac). Quando a página de boas-vindas for exibida no navegador, insira um número e clique em submeter. A página de resposta é semelhante à seguinte (contanto que você não adivinhe o número correto).
    página de resposta exibida no navegador

    Há duas coisas erradas com o status atual da página de resposta:

    1. As marcas html <p> são exibidas na mensagem de resposta.
    2. O botão Voltar não é exibido no lugar correto. (Compare-a à versão original.)

    As duas etapas seguintes corrigem estes pontos, respectivamente.

  8. Defina, da marcação <h:outputText>, o atributo escape como falso. Coloque o cursor entre outputText e valor, insira um espaço e pressione Ctrl-Espaço para chamar o autocompletar de código. Role para baixo para escolher o atributo escape e examine a documentação.
    Sugestões do auto-completar código e documentação exibidos no editor

    Conforme indicado pela documentação, o valor escape está definido como verdadeiro por padrão. Isso significa que os caracteres que seriam normalmente analisados como html são incluídos na string, conforme ilustrado acima. Definir o valor como false permite que os caracteres que podem ser analisados como html sejam processados como tal.

    Clique em Indicar e digite false como valor.

    <h4><h:outputText escape="false" value="#{UserNumberBean.response}"/></h4>
  9. Defina, da marcação <h:form>, o atributo prependId como falso. Coloque o cursor logo depois de 'm' em <h:form>, insira um espaço e pressione Ctrl-Espaço para chamar o autocompletar de código. Navegue para baixo a fim de escolher o atributo prependId e examine a documentação. Clique em Enter e digite false como valor.
    <h:form prependId="false">

    O JSF aplica IDs internas para controlar os componentes de UI. No exemplo atual, se examinar o código-fonte da página processada, verá algo semelhante ao seguinte:

    <form id="j_idt5" name="j_idt5" method="post" action="/jsfDemo/faces/response.xhtml" enctype="application/x-www-form-urlencoded">
    <input type="hidden" name="j_idt5" value="j_idt5" />
        <input id="j_idt5:backButton" type="submit" name="j_idt5:backButton" value="Back" />
        <input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="7464469350430442643:-8628336969383888926" autocomplete="off" />
    </form>

    A id do elemento do formulário é j_idt5 e essa id é precedida pela id do botão Voltar incluído no formulário (ilustrado em negrito acima). Como o botão Voltar depende da regra de estilo do #backButton (definido em stylesheet.css), esta regra se torna um empecilho quando a id do JSF é colocada é precedida. Isso pode ser evitado ao definir prependId como false.

  10. Execute novamente o projeto (clique no botão Executar projeto (botão Executar projeto) ou pressione F6; fn-F6 no Mac). Insira um número na página de boas-vindas e clique em Submeter. A página de resposta exibe agora a mensagem de resposta sem as marcas <p> e o botão Voltar está no lugar correto.
    página de resposta exibida no navegador
  11. Clique no botão Voltar. Devido a que o valor atual da propriedade userNumber do UserNumberBean está vinculado ao componente JSF inputText, o número inserido anteriormente é agora exibido no campo de texto.
  12. Examine o registro do servidor na janela Saída do IDE (Ctrl-4; &#8984-4 no Mac) para determinar qual é o suposto número correto.

    Se, por alguma razão, não puder ver o log do servidor, você pode abri-lo passando para a janela Serviços (Ctrl-5; &#8984-5 no Mac) e expandindo o nó Servidores. Em seguida, clique com o botão direito do mouse no servidor GlassFish no qual o projeto está implantado e escolha Exibir log do servidor. Se não conseguir ver o número no registro do servidor, tente recompilar o aplicativo clicando com o botão direito do mouse no nó do projeto e selecionando Limpar e compilar projeto.

  13. Digite o número correto e clique em Submeter. O aplicativo compara o número inserido com o número atualmente salvo e exibe a mensagem apropriada.
    página de resposta exibida no navegador
  14. Clique novamente no botão Voltar. Observe que o número inserido anteriormente não é mais exibido no campo de texto. Lembre-se que o método getResponse() do UserNumberBean invalida a sessão atual do usuário quando o número correto é descoberto.

Aplicando um modelo Facelets

O Facelets tornou-se a tecnologia de exibição padrão do JSF 2.0. O Facelets é uma estrutura de modelagem que suporta todos os componentes da UI do JSF e é utilizado para construir e processar a árvore de componentes JSF das visualizações do aplicativo. Também oferece suporte ao desenvolvimento quando ocorrem erros de EL, pois permite que você examine o rastreamento de pilha, a árvore de componentes e as variáveis com escopo.

Embora você talvez não tenha percebido, os arquivos index.xhtml e response.xhtml com os quais você trabalhou no tutorial são páginas Facelets. As páginas Facelets utilizam a extensão .xhtml e, desde que você esteja trabalhando em um projeto JSF 2.0 (As bibliotecas JSF 2.0 incluem arquivos JAR Facelets.), as visualizações podem processar apropriadamente a árvore de componentes JSF.

O objetivo desta seção é familiarizar você com a modelagem Facelets. Em projetos que contêm várias visualizações, geralmente é mais vantajoso aplicar um arquivo de modelo que defina a estrutura e a aparência das visualizações múltiplas. Ao atender as requisições, o aplicativo insere dinamicamente o conteúdo preparado no arquivo de modelo e envia o resultado de volta ao cliente. Embora esse projeto contenha somente duas visualizações (a página de boas-vindas e página de resposta), é fácil visualizar que contém uma grande quantidade de conteúdo duplicado. É possível fatorar esse conteúdo duplicado em um modelo Facelets e criar arquivos clientes de modelo para manipular o conteúdo específico das páginas boas-vindas e resposta.

O IDE proporciona um assistente do modelo Facelets para a criação de modelos Facelets e um assistente de cliente do modelo Facelets para a criação de arquivos que dependem de um modelo. Esta seção utiliza esses assistentes.

Nota: o IDE também proporciona um assistente de página JSF que permite criar páginas Facelets individuais para seu projeto. Para mais informações, consulte Suporte JSF 2.0 no NetBeans IDE.

Criando o arquivo de modelo Facelets

  1. Crie um arquivo de modelo Facelets. Pressione Ctrl-N (&#8984-N no Mac) para abrir o assistente Arquivo. Selecione a categoria JavaServer Faces e, em seguida, Modelo Facelets. Clique em Avançar.
  2. Digite template como nome do arquivo.
  3. Escolha um dos oito estilos de layout e clique em Terminar. (A folha de estilos utilizada é uma folha de estilo existente, de modo que não importa o estilo de layout escolhido.)
    Estilos de layout apresentados no assistente para modelo Facelets
    O assistente gera o arquivo template.xhtml e relaciona as folhas de estilo com base na seleção feita, a seguir, coloca-as em uma pasta resources > css dentro da webroot do projeto.

    Depois de concluir o assistente, o arquivo de modelo é aberto no editor. Para visualizar o modelo em um navegador, clique com o botão direito do mouse no Editor e escolha Visualizar.

  4. Examine a remarcação do arquivo de modelo. Observe os pontos seguintes:
    • A biblioteca de marcações facelets é declarada na marcação <html> da página. A biblioteca de marcas possui o prefixo ui.
      <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:h="http://java.sun.com/jsf/html">
    • A página Facelets utiliza as marcações <h:head> e <h:body> em vez das marcações <head> e <body>. Ao utilizar essas marcações, o Facelets pode construir uma árvore de componentes que abrange toda a página.
    • A página faz referência às folhas de estilo que também foram criadas ao concluir o assistente.
      <h:head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
          <link href="./resources/css/default.css" rel="stylesheet" type="text/css" />
          <link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" />
          <title>Facelets Template</title>
      </h:head>
    • As marcações <ui:insert> são utilizadas no corpo da página em todos os compartimentos associados ao estilo de layout que você escolheu. Cada marcação <ui:insert> possui um atributo nome que identifica o compartimento. Por exemplo:
      <div id="top">
          <ui:insert name="top">Top</ui:insert>
      </div>
  5. Re-examine as páginas de boas-vindas e de resposta. O único conteúdo que é modificado nas duas páginas é o título e o texto contido no quadro cinza. O modelo, portanto, pode proporcionar todo o conteúdo restante.
  6. Substitua todo o conteúdo de seu arquivo de modelo pelo conteúdo abaixo.
    <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:h="http://java.sun.com/jsf/html">
    
        <h:head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <link href="css/stylesheet.css" rel="stylesheet" type="text/css" />
    
            <title><ui:insert name="title">Facelets Template</ui:insert></title>
        </h:head>
    
        <h:body>
    
            <div id="left">
                <ui:insert name="box">Box Content Here</ui:insert>
            </div>
    
        </h:body>
    
    </html>
    O código abaixo implementa as seguintes alterações:
    • O arquivo stylesheet.css do projeto substitui as referências da folha de estilo do modelo criada pelo assistente.
    • Todas as marcas <ui:insert> (e suas marcas <div>) foram removidas, exceto uma denominada box.
    • Um par de marcas <ui:insert> foi colocado na página de título e foi denominado title.
  7. Copie o código relevante do arquivo index.xhtml ou do response.xhtml para o modelo. Adicione o conteúdo mostrado em negrito abaixo das marcas <h:body> do arquivo de modelo.
    <h:body>
        <div id="mainContainer">
            <div id="left" class="subContainer greyBox">
                <ui:insert name="box">Box Content Here</ui:insert>
            </div>
            <div id="right" class="subContainer">
                <img src="duke.png" alt="Duke waving" />
            </div>
        </div>
    </h:body>
  8. Execute o projeto. Quando a página de boas-vindas se abrir no navegador, modifique o URL para o seguinte:
    http://localhost:8080/jsfDemo/faces/template.xhtml
    O arquivo de modelo é exibido da seguinte forma:
    Modelo Facelets exibido no navegador

O projeto agora contém um arquivo modelo que fornece a aparência e a estrutura de todas as visualizações. Agora é possível criar arquivos clientes que chamem o modelo.

Criando arquivos clientes de modelo

Crie os arquivos clientes modelo das páginas boas-vindas e resposta. Nomeie o arquivo cliente modelo da página de boas-vindas greeting.xhtml. Para a página de resposta, o arquivo será response.xhtml.

greeting.xhtml

  1. Pressione Ctrl-N (⌘-N no Mac) para abrir o assistente Novo arquivo. Selecione a categoria JavaServer Faces e, em seguida, Cliente modelo Facelets. Clique em Avançar.
  2. Digite greeting como nome do arquivo.
  3. Clique no botão Procurar ao lado do campo Modelo e, em seguida, utilize a caixa de diálogo exibida para navegar até o arquivo template.xhtml criado na seção anterior.
    Assistente de cliente de modelo Facelets
  4. Clique em Terminar. O novo arquivo cliente de modelo greeting.xhtml é gerado e exibido no editor.
  5. Examine a remarcação. Observe o conteúdo realçado em negrito.
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets">
    
        <body>
    
            <ui:composition template="./template.xhtml">
    
                <ui:define name="title">
                    title
                </ui:define>
    
                <ui:define name="box">
                    box
                </ui:define>
    
            </ui:composition>
    
        </body>
    </html>
    O arquivo cliente modelo faz referência a um modelo utilizando, da marcação <ui:composition>, o atributo modelo. Como o modelo contém marcações <ui:insert> de título e caixa, esse cliente modelo contém as marcações <ui:define> desses dois nomes. O conteúdo especificado entre as marcas <ui:define> será o conteúdo inserido no modelo entre as marcas <ui:insert> do nome correspondente.
  6. Especifique greeting como o título do arquivo. Faça a alteração seguinte em negrito.
    <ui:define name="title">
        Greeting
    </ui:define>
  7. Alterne para o arquivo index.xhtml (pressione Ctrl-Tab) e copie o conteúdo que normalmente aparece no quadro cinza exibido na página processada. Em seguida, volte ao greeting.xhtml e cole-o no arquivo cliente modelo. (Alterações em negrito.)
    <ui:define name="box">
        <h4>Hi, my name is Duke!</h4>
    
        <h5>I'm thinking of a number
    
            <br/>
            between
            <span class="highlight">0</span> and
            <span class="highlight">10</span>.</h5>
    
        <h5>Can you guess it?</h5>
    
        <h:form>
            <h:inputText size="2" maxlength="2" value="#{UserNumberBean.userNumber}" />
            <h:commandButton id="submit" value="submit" action="response" />
        </h:form>
    </ui:define>
  8. Declare a biblioteca de marcações HTML JSF do arquivo. Coloque o cursor em qualquer uma das marcações que estão sinalizadas com um erro (qualquer marca com prefixo h') e pressione Ctrl-Espaço. Em seguida, selecione a marcação na lista de sugestões do autocompletar de código. O namespace da biblioteca de marcas é adicionado à marca <html> do arquivo (mostrado em negrito abaixo) e os indicadores de erro desaparecem.
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:h="http://java.sun.com/jsf/html">

    Se colocar o cursor depois de 'm' no <h:form> e pressionar Ctrl-Espaço, o namespace é automaticamente adicionado ao arquivo. Se somente uma opção lógica estiver disponível ao pressionar Ctrl-Espaço, ela será imediatamente aplicada ao arquivo. As bibliotecas de marcas JSF são automaticamente declaradas ao chamar o auto-completar código nas marcas.

response.xhtml

Como o projeto já contém um arquivo denominado response.xhtml e visto que você já sabe qual é a aparência do arquivo cliente modelo, modifique o response.xhtml para que se torne o arquivo cliente modelo. (Neste tutorial, basta copiar e colar o código fornecido.)

  1. Abra response.xhtml no editor. (Se já estiver aberto, pressione Ctrl-Tabulação e selecione-o.) Substitua o conteúdo de todo o arquivo pelo código abaixo.
    <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:h="http://java.sun.com/jsf/html">
        <body>
            
            <ui:composition template="./template.xhtml">
    
                <ui:define name="title">
                    Response
                </ui:define>
    
                <ui:define name="box">
                    <h4><h:outputText escape="false" value="#{UserNumberBean.response}"/></h4>
    
                    <h:form prependId="false">
    
                        <h:commandButton id="backButton" value="Back" action="greeting" />
    
                    </h:form>
                </ui:define>
    
            </ui:composition>
    
        </body>
    </html>
    Observe que o arquivo é idêntico a greeting.xhtml, exceto pelo conteúdo especificado entre as marcas <ui:define> de title e box.
  2. No descritor de deployment web.xml do projeto, modifique a entrada do arquivo de boas-vindas para que greeting.xhtml seja a página exibida quando o aplicativo for executado.

    Na janela Projetos, clique duas vezes em Arquivos de configuração > web.xml para abri-lo no editor. Na aba Páginas, altere o campo Arquivos de boas-vindas para faces/greeting.xhtml.
    Interface do descritor de deployment
  3. Execute o projeto para ver sua aparência em um navegador. Pressione F6 (fn-F6 no Mac), ou clique no botão Executar projeto (botão Executar projeto) na barra de ferramentas principal. O projeto é implantado ao servidor GlassFish e aberto em um navegador.

Ao utilizar o modelo Facelets e arquivos clientes modelo, o aplicativo se comporta exatamente da mesma forma que antes. Ao fatorar o código duplicado nas páginas de boas-vindas e de resposta do aplicativo, você consegue reduzir o tamanho do aplicativo e eliminar a possibilidade de escrever mais códigos duplicado, caso mais páginas sejam adicionadas depois. Isso pode tornar o desenvolvimento mais fácil e eficiente em grandes projetos.


Consulte também

Para mais informações sobre o JSF 2.0, consulte os recursos a seguir.