Avançar para a área de conteúdo

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Todas as informações enviadas são seguras.

  • Fechar [x]

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Todas as informações enviadas são seguras.

  • Fechar [x]

JSF 2 fu: Componentes compostos Ajax de última hora

Permita que os autores de página incluam o Ajax nos seus componentes compostos

David Geary, President, Clarity Training, Inc.
David Geary
O autor, palestrante e consultor David Geary é o presidente da Clarity Training, Inc. onde ensina desenvolvedores a implementarem aplicativos da Web usando JSF e Google Web Toolkit (GWT). Ele fez parte dos Grupos de Especialistas do JSTL 1.0 e do JSF 1.0/2.0, foi coautor do Exame de Certificação de Desenvolvedor da Web da Sun e contribuiu para projetos de software livre, incluindo o Apache Struts e o Apache Shale. Graphic Java Swing de David foi um dos livros de Java mais vendidos de todos os tempos e Core JSF (coescrito com Cay Horstman) é o livro de JSF mais vendido. David fala frequentemente em conferências e para grupos de usuários. É frequentador assíduo do tour de NFJS desde 2003, deu cursos na Java University e foi duas vezes votado como JavaOne rock star.

Resumo:  David Geary, membro de Grupo de Especialistas em Java™Server Faces (JSF) 2, continua sua série de artigos oferecendo uma cobertura detalhada da tecnologia JSF 2. Neste artigo, você aprenderá como permitir aos autores de páginas a inclusão de Ajax nos seus componentes compostos, observando atentamente a poderosa — e não documentada — tag do JSF 2.0. Você verá também como implementar um componente de ícone reutilizável e de uso geral ativado para Ajax em menos de 25 linhas de XML.

Visualizar mais conteúdo nesta série

Data:  17/Mai/2011
Nível:  Intermediário Também disponível em :   Inglês
Atividade:  1645 visualizações
Comentários:  


Sobre esta série

A série JSF 2 fu, uma continuação da introdução com três artigos de David Geary com o mesmo nome, ajudará você a desenvolver e aprimorar seus conhecimentos da estrutura do JSF 2 com um mestre de kung fu . A série atual abrange em detalhes a estrutura e os ecossistemas circundantes. E também espia fora da caixa mostrando como algumas tecnologias Java EE, como os Contextos e a Injeção de Dependência, se integram com o JSF.

No artigo anterior do JSF 2 fu, eu discuti a implementação de um componente composto de preenchimento automático com o Ajax integrado. Os autores de páginas usam o componente em um facelet e o componente cuida de todos os detalhes do Ajax. O Ajax integrado possui seu lugar, mas também é conveniente permitir aos autores de páginas a inclusão de Ajax no componente composto depois (talvez bem depois) de o desenvolvedor ter implementado o componente. Este artigo mostra como os seus componentes compostos podem acomodar o Ajax de última hora.

Conforme discutido no artigo "JSF 2 fu, Parte 3: Manipulação de Eventos, JavaScript e Ajax", a tag <f:ajax> do JSF 2 permite aos autores de páginas a inclusão de Ajax de última hora aos componentes integrados do JSF 2. Por exemplo: com a <f:ajax> é possível facilmente transformar um botão de envio em um botão do Ajax:

<h:commandButton value="Click me">
  <f:ajax>
</h:commandButton>

No entanto, a tag <f:ajax> do JSF 2 não funciona — sem uma pequena ajuda — com componentes compostos, pois os compostos são simplesmente contêineres de componentes.

Por exemplo: no artigo "JSF 2 fu, Parte 2: Uso de modelos e componentes compostos", eu introduzi um componente composto de ícone simples que consiste em um link, representado por uma imagem. Quando o usuário clique no ícone, o ícone envia o formulário circundante, que aciona um listener de ação do lado do servidor associado ao link do ícone. O uso de ícones é simples:

<util:icon image="...">
  <f:actionListener for="link" type="...">
</util:icon>

Como é possível transformar botões de envio em botões de AjaComx com a tag <f:ajax> , você pode pensar que é possível fazer a mesma coisa para ícones:

<util:icon image="...">
  <f:ajax>
  <f:actionListener for="link" type="...">
</util:icon>

O fragmento de código anterior não funciona, pois estou anexando a tag <f:ajax> no componente de ícone, quando o que realmente desejo fazer é anexá-la ao link dentro do ícone.

O necessário neste exemplo é um mecanismo que permita a conexão do comportamento do Ajax ao link dentro do ícone, ou de forma mais geral, que permita a conexão do componente do Ajax aos componentes que residem nos componentes compostos. Esse mecanismo — implementados no Mojarra e Apache MyFaces e que não possuem documentação no JSF 2.0 — é o foco deste artigo. (Observação: O suporte ao MyFaces foi incluído enquanto este artigo estava sendo escrito.) Antes de ver como o mecanismo funciona, irei criar um novo componente composto de ícone para uso com o mecanismo.

Executando o código de amostra

O código desta série é baseado no JSF 2 em execução em um contêiner corporativo, como o GlassFish ou Resin. Consulte o artigo "JSF 2 fu: Componentes Ajax" para obter um tutorial passo a passo de instalação e execução do código desta série com o GlassFish. Consulte a seção Download para obter o código de amostra deste artigo.

Um componente de ícone reutilizável

Imagine que você tem a profissão mais legal do mundo. Talvez você esteja implementado o mecanismo de gráfico World of Warcraft de última geração. Mas infelizmente não hoje. Hoje você implementará o seletor de fonte mostrado na Figura 1:


Figura 1. Selecionando uma fonte

Seus chefes perguntam quanto tempo vai demorar essa implementação. Eles querem os ícones de + e - que os usuários podem clicar para alterar o tamanho da fonte na visualização com dois caracteres. Obviamente eles querem o uso de Ajax para que a visualização e a exibição do tamanho próximas aos ícones atualizem dinamicamente sem interferir no resto da página.

Os seus chefes esperam um componente simples de seleção de fonte, mas você fará melhor. Você implementará um componente de ícone de uso geral que pode ser configurado no tempo de execução com uma imagem e uma ação, totalmente preparado para Ajax, e usará o componente de ícone na visualização da fonte. Dessa forma, você terá um componente de ícone útil que será muito conveniente no futuro.

Agora irei mostrar como implementar o componente de ícone em menos de 25 linhas de XML.


O exemplo do seletor de fonte

Componentes compostos: Informações básicas

Se não estiver familiarizado com o uso ou a implementação dos componentes compostos do JSF 2, será possível localizar uma introdução no artigo "JSF 2 fu, Parte 2: Uso de modelos e componentes compostos."

O exemplo de seletor de fonte consiste em quatro arquivos:

  • A página mostrada na Figura 1, definida no index.xhtml.
  • O componente de ícone, que reside em /resources/util/icon.xhtml.
  • Um listener (com.clarity.FontSelectionListener.java).
  • Um bean (com.clarity.FontSettings).

A Figura 2 mostra a estrutura de diretório:


Figura 2. Os arquivos do exemplo de seletor de fonte

A Listagem 1 é o facelet — index.xhtml — da página mostrada na Figura 1:


Listagem 1. O facelet (/web/index.xhtml)
<?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:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html" 
      xmlns:corejsf="http://corejsf.com"
      xmlns:util="http://java.sun.com/jsf/composite/util">

   <h:head>
      <h:outputStylesheet library="css" name="styles.css"/>
      <title>#{msgs.windowTitle}</title>
   </h:head>
   
   <h:body> 
      <h:outputStylesheet library="css" name="styles.css"/>
      
      <h:outputText value="#{msgs.fontSizeHeading}"
        style="padding-left: 30px; font-size: 2em;"/>
      
      <h:panelGrid columns="3" style="padding-left: 80px;">
        <util:icon id="minus" image="#{resource['images:minus.gif']}">
          <f:actionListener for="link" type="com.clarity.FontSelectionListener"/>
        </util:icon>

        <util:icon id="plus" image="#{resource['images:plus.gif']}">
          <f:actionListener for="link" type="com.clarity.FontSelectionListener"/>

        </util:icon>
        
        <h:outputText id="readout" value="#{fontSettings.size}em"/>
      </h:panelGrid>
            
      <h:outputText id="fontPreview" value="Aa" 
                 style="font-size: #{fontSettings.size}em; font-style: italic"/>

   </h:body>
</html>

O facelet na Listagem 1 declara um namespace para o componente de ícone e usa o componente na página. Esse é o uso de componentes compostos 101 do JSF 2.0, abrangido em detalhes no artigo "JSF 2 fu, Parte 2: Uso de modelos e componentes compostos."

Observe que os dois ícones são equipados com um listener de ação para o componente do link do ícone. Quando um usuário clica no link do ícone, o JSF invoca esse listener, mostrado na Listagem 2, no servidor.


Listagem 2. O listener (com/clarity/FontSelectionListener.java)
package com.clarity;

import javax.el.ELResolver;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;

public class FontSelectionListener implements ActionListener {
   @Override
   public void processAction(ActionEvent event)
         throws AbortProcessingException {
    FacesContext c = FacesContext.getCurrentInstance();
    ELResolver elResolver = c.getApplication().getELResolver();
    FontSettings fs = (FontSettings) 
      elResolver.getValue(c.getELContext(), null, "fontSettings");
    
    if (((UIComponent)event.getSource()).getClientId().startsWith("minus"))
      fs.decrement();
    else
      fs.increment();
   }
}

Na Listagem 2, olhei para ver se o identificador de cliente do componente que acionou o evento é minus; se for, sei que o usuário clicou no ícone do sinal de menos, e eu reduzo o tamanho da fonte. Caso contrário, eu aumento o tamanho da fonte.

Observe que o listener obtém uma referência para o bean gerenciado fontSettings . Ele faz isso obtendo uma referência para o resolvedor de idioma de expressão, que sabe como localizar beans gerenciados de acordo com seus nomes. O bean fontSettings é mostrado na Listagem 3:


Listagem 3. O bean de configuração de fonte (com/clarity/FontSettings.java)
package com.clarity;

import java.io.Serializable;

import javax.inject.Named; 
import javax.enterprise.context.SessionScoped; 

@Named
@SessionScoped
public class FontSettings implements Serializable {
   private static int INCREMENT = 1;
   private int size = 1;
   
   public int getSize() { return size; }
   public void setSize(int newValue) { size = newValue; }

   public void increment() { size += INCREMENT; }
   public void decrement() { size -= INCREMENT; }
}

As três listagens anteriores mostram todo o código no aplicativo, com exceção do componente composto de ícone. Ele é o item seguinte.


Implementando o componente composto de ícone

Os ícones possuem três requisitos:

  • A imagem deve ser configurável.
  • A ação quando o usuário clica na imagem deve ser configurável.
  • O ícone deve oferecer suporte para Ajax.

Na Listagem 4, eu cumpro os dois primeiros requerimentos:


Listagem 4. O componente composto <util:icon> , parte 1 (/resources/util/icon.xhtml)
<!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:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:composite="http://java.sun.com/jsf/composite">
    
    <composite:interface>
      <composite:attribute    name="image" required="true"/>
      <composite:actionSource name="link"  targets="#{cc.clientId}:iconForm:link"/>
    </composite:interface>

    <composite:implementation>
      <div id="#{cc.clientId}">
         <h:form id="iconForm">
            <h:commandLink id="link" immediate="true">
              <h:graphicImage value="#{cc.attrs.image}"/>
            </h:commandLink>
         </h:form>
       </div>
    </composite:implementation>    
</html>

O componente de ícone na Listagem 4 declara um atributo de imagem e um actionSource chamado link. Esse actionSource é usado na Listagem 1 como o valor do atributo for do <f:actionListener> . Se não ficar completamente claro, será possível ler mais sobre como as fontes de ação funcionam nos componentes compostos no artigo "JSF 2 fu, Parte 2: Uso de modelos e componentes compostos", que discute brevemente uma implementação de ícone similar à implementação da Listagem 4.

A implementação do componente de ícone na Listagem 4 permite ao autor de páginas a configuração da aparência e do comportamento dos ícones, mas não permite ao autor a conexão de comportamentos de Ajax ao componente. De acordo com a implementação atual, se o usuário clicar em uma imagem, o JSF envia a página completa e redesenha completamente a página ao retornar.

Agora você verá como permitir aos autores de páginas a inclusão de Ajax ao componente de ícone.


Incluindo suporte para Ajax com <composite:clientBehavior>

Para permitir aos autores de páginas a inclusão de Ajax no link presente no componente <util:icon> , eu uso a tag <composite:clientBehavior> , conforme mostrado na Listagem 5:


Listagem 5. O componente composto <util:icon>, parte 2
<!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:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:composite="http://java.sun.com/jsf/composite">
    
    <composite:interface>
      <composite:attribute      name="image" required="true"/>
      <composite:actionSource   name="link"  targets="#{cc.clientId}:iconForm:link"/>
     <composite:clientBehavior name="click" 
                              event="action"
                            targets="#{cc.clientId}:iconForm:link"/>
    </composite:interface>

    <composite:implementation>
      <div id="#{cc.clientId}">
         <h:form id="iconForm">
            <h:commandLink id="link" immediate="true">
              <h:graphicImage value="#{cc.attrs.image}"/>
            </h:commandLink>
         </h:form>
       </div>
    </composite:implementation>    
</html>

Não documentado: <composite:clientBehavior>

A tag <composite:clientBehavior> foi detalhada por um subgrupo do Grupo de Especialistas em JSF 2.0. Ela foi implementada na implementação de referência do JSF (Mojarra), mas não foi documentada para o JSF 2.0; por isso, você não encontrará nenhuma menção a ela no Javadocs e na especificação do JSF.

A documentação ausente é conhecida como um erro de especificação (consulte a seção Recursos para obter um link para mais informações). O Grupo de Especialistas em JSF garantiu que o erro será corrigido com a inclusão da documentação na especificação e no Javadocs.

A tag <composite:clientBehavior> expõe um evento de Ajax para um componente contido em um componente composto. Na Listagem 5, eu declaro um comportamento de cliente com o nome lógico click associado ao evento real — o evento action disparado pelo link do ícone. Aqui está um resumo dos atributos válidos da tag <composite:clientBehavior> :

  • name: O nome do evento usado pelos autores de páginas.
  • default: Pode ser true ou false. Se for true, o evento especificado no atributo name será o evento padrão.
  • event: O nome real do evento.
  • targets: Uma lista separada por espaço dos IDs de componentes para os quais o JSF redireciona o comportamento.

Agora os autores de páginas podem conectar os comportamentos de Ajax ao componente de ícone, conforme mostrado na Listagem 6:


Listagem 6. O facelet, parte 2
<?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:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html" 
      xmlns:corejsf="http://corejsf.com"
      xmlns:util="http://java.sun.com/jsf/composite/util">

   <h:head>
      <h:outputStylesheet library="css" name="styles.css"/>
      <title>#{msgs.windowTitle}</title>
   </h:head>
   
   <h:body> 
      <h:outputStylesheet library="css" name="styles.css"/>
      
      <h:outputText value="#{msgs.fontSizeHeading}"
        style="padding-left: 30px; font-size: 2em;"/>
      
      <h:panelGrid columns="3" style="padding-left: 80px;">
        <util:icon id="minus" image="#{resource['images:minus.gif']}">
          <f:ajax event="click" render=":readout :fontPreview"/>
          <f:actionListener for="link" type="com.clarity.FontSelectionListener"/>
        </util:icon>

        <util:icon id="plus" image="#{resource['images:plus.gif']}">
          <f:ajax event="click" render=":readout :fontPreview"/>
          <f:actionListener for="link" type="com.clarity.FontSelectionListener"/>
        </util:icon>
        
        <h:outputText id="readout" value="#{fontSettings.size}em"/>
      </h:panelGrid>
            
      <h:outputText id="fontPreview" value="Aa" 
                 style="font-size: #{fontSettings.size}em; font-style: italic"/>

   </h:body>
</html>

Renderizando componentes fora de um componente composto

Na Listagem 6, eu especifico os componentes readout e fontPreview para o atributorender da tag <f:ajax> . Observe que eu prefaciei os identificadores do componente com dois pontos.

Os dois pontos forçam o JSF a procurar os componentes a partir da parte superior da hierarquia do componente, caso contrário o JSF procuraria no contêiner de nomenclatura (normalmente um formulário) próximo ao componente no qual o Ajax está conectado. No caso do ícone, o componente é o link do ícone, e o formulário é o formulário do ícone que contém o link. Se você remover os dois pontos, o JSF iniciará a procura dos componentes readout e fontPreview no formulário do ícone. Eles não serão encontrados, o que gerará um erro.

Na Listagem 6, eu incluí uma tag <f:ajax> nos ícones. Quando o usuário clica em um dos ícones, o JSF cria uma chamada de Ajax para o servidor, e quando a chamada retorna, o JSF renderiza os componentes readout e fontPreview .

Se preferir, será possível incluir um atributo default="true" na tag <composite:clientBehavior> na interface do ícone. Isso elimina a necessidade de especificação do evento click pelo autor de página, reduzindo as tags <f:ajax> na Listagem 6 para <f:ajax render=":readout :fontPreview">.


Conclusão

Neste artigo, mostrei como o JSF 2 facilita, mesmo com uma tag não documentada, a inclusão de funcionalidades do Ajax nos componentes compostos pelos autores de páginas. Realmente, conforme visto, é possível fornecer aos autores de páginas a capacidade de transformação de componentes compostos que fazem solicitação de HTTP completas em componentes que fazem solicitações Ajax. E tudo isso é o resultado de uma única linha de XML em uma interface do componente composto.

No próximo artigo do JSF 2 fu, vou deixar os componentes compostos um pouco de lado para abordar o uso dos Contextos e Injeção de Dependência (CDI) com o JSF 2.



Download

DescriçãoNomeTamanhoMétodo de download
Sample code for this articlej-jsf2fu-0610-src.zip11KBHTTP

Informações sobre métodos de download


Recursos

Aprender

Obter produtos e tecnologias

  • JSF: Faça o download do JSF 2.0.

Discutir

Sobre o autor

David Geary

O autor, palestrante e consultor David Geary é o presidente da Clarity Training, Inc. onde ensina desenvolvedores a implementarem aplicativos da Web usando JSF e Google Web Toolkit (GWT). Ele fez parte dos Grupos de Especialistas do JSTL 1.0 e do JSF 1.0/2.0, foi coautor do Exame de Certificação de Desenvolvedor da Web da Sun e contribuiu para projetos de software livre, incluindo o Apache Struts e o Apache Shale. Graphic Java Swing de David foi um dos livros de Java mais vendidos de todos os tempos e Core JSF (coescrito com Cay Horstman) é o livro de JSF mais vendido. David fala frequentemente em conferências e para grupos de usuários. É frequentador assíduo do tour de NFJS desde 2003, deu cursos na Java University e foi duas vezes votado como JavaOne rock star.

Ajuda para Relatar Abuso

Relatar abuso

Obrigado. Esta entrada foi sinalizada para atenção do moderador.


Ajuda para Relatar Abuso

Relatar abuso

Falha no envio do Relatório de abuso. Tente novamente mais tarde.


developerWorks: Registre-se


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Selecione seu nome de exibição

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

(Deve possuir de 3 a 31 caracteres.)


Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Classificar este artigo

Comentários

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Tecnologia Java
ArticleID=658136
ArticleTitle=JSF 2 fu: Componentes compostos Ajax de última hora
publish-date=05172011
author1-email=david.mark.geary@gmail.com
author1-email-cc=

Conheça a IBM da sua cidade

Virtual Branch Office Brasil

A IBM está mais perto do que você imagina!


Tags

Help
Use o campo de pesquisa para encontrar todos os tipos de conteúdo no My developerWorks com essa tag.

Use a barra de rolagem para ver mais ou menos tags.

Tags populares mostra as principais tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Minhas tags mostra suas tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Use o campo de pesquisa para localizar todos os tipos de conteúdo no Meu developerWorks com essa tag. Tags populares mostra as tags principais para essa zona de conteúdo particular (por exemplo, tecnologia Java, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere). Minhas tags mostra as suas tags para essa zona de conteúdo em particular (por exemplo, tecnologia Java, Linux, WebSphere).