Você está na página 1de 186

1

2
O objetivo deste capítulo é apresentar as principais características da
tecnologia Java Server Faces, além de apresentar também algumas
mudanças que ocorreram durante as verões.

3
JSF é uma tecnologia que nos permite criar aplicações Java para Web
utilizando componentes visuais, fazendo com que o desenvolvedor não
se preocupe com Javascript e HTML. Basta adicionarmos os
componentes (calendários, tabelas, formulários) que eles serão
renderizados e exibidos em formato html.

JSF tem é composto pelas seguintes partes:


• Um conjunto de componentes pré-fabricados (interface de usuário)
• Um modelo de programação orientada a eventos
• Um modelo de componente que permite que desenvolvedores
terceiros para fornecer componentes adicionais.

4
Alguns componentes JSF são simples, tais como campos de entrada e
botões. Outros são bastante sofisticado , como , tabelas de dados e
árvores.

JSF contém todo o código necessário para a manipulação de eventos e


organização dos componentes. JSF não é o único framework web
baseado em componentes , mas é a camada de visão padrão Java EE.
JSF está incluído em cada servidor de aplicativos Java EE, e pode ser
facilmente adicionado a um container Web como o Tomcat .

Diferentemente da maioria dos frameworks web , JSF é um padrão


com várias implementações . Isto permite uma escolha de
fornecedores.

5
Outra característica marcante na arquitetura do JSF é a separação que
fazemos entre as camadas de apresentação e de aplicação. Pensando
no modelo MVC, o JSF possui uma camada de visualização que, por
padrão, se baseia nos Facelets e um conjunto de classes conhecidas
como Managed Beans; ambos veremos com mais detalhes.

6
O MVC (model-view-controller) é um padrão de arquitetura que tem por
objetivo isolar a lógica de negócio da lógica de apresentação de uma
aplicação.
Esse padrão (ou alguma variação) é amplamente adotado nas
principais plataformas de desenvolvimento atuais. Em particular, ele é
bastante utilizado na plataforma Java.
O padrão MVC divide uma aplicação em três tipos de componentes:
modelo, visão e controlador.

Modelo: encapsula os dados e as funcionalidades da aplicação.


Visão: é responsável pela exibição de informações, cujos dados são
obtidos do modelo.
Controlador: recebe as requisições do usuário e aciona o modelo e/ou
a visão.

7
Baseado nesta especificação, há várias implementações. A mais
famosa, e também implementação referencial (RI), é a Oracle Mojarra
disponível em http://javaserverfaces.java.net/, aquela que mostra como
o JSF deveria se comportar. Outra implementação famosa é da Apache
Software Foundation, e se chama MyFaces
(http://myfaces.apache.org/).

8
Analisando um pouco melhor o JSF, percebemos que ele é na verdade
um padrão ou especificação que faz parte do Java Enterprise
Edition (Java EE). Por ser uma especificação, ou Java Specification
Request (JSR), ele é mantido dentro do Java Community
Process (JCP).

9
A especificação do JSF pode ser acessada no site da
JCP: http://jcp.org/en/jsr/detail?id=314

10
Ciclo de vida do JSF é o nome dado à sequência de processamento
realizada na implementação JSF para a geração das visões. O JSF,
diferente de outros frameworks, pois possui um processamento de
requisição dividido em seis fases:

1 - Restauração da visão - o objetivo principal desta fase é construir


a árvore de componentes. Ela utiliza o template e cria a árvore inicial
através da análise da requisição. Após isto, ela salva o estado da
árvore no objeto FacesContext. Nas requisições subsequentes, ela cria
a árvore do estado e procede a execução do resto do ciclo de vida.

2 - Aplicação dos valores de requisição - o JSF pega cada componente


da árvore começando com a raiz e a cria ou recupera do
objeto FacesContext. Cada componente na árvore gerencia seus
próprios valores e toma-os dos parâmetros, cookies e cabeçalhos da
requisição HTTP.

3 - Validações de processo - o JSF realiza a conversão e validação


sobre todos os componentes começando com o raiz. O valor submetido
de cada componente é convertido em um objeto e validado chamando-

11
se o validador registrado. O JSF salva o valor submetido. Se ocorrer um erro
durante a conversão ou validação, o ciclo de vida escapa diretamente para a
faze de "apresentação da resposta".

4 - Atualização de valores de modelo - durante esta fase, o valor do


componente é passado para o modelo através da atualização das
propriedades dos backing beans.

5 - Invocação da aplicação - a manipulação de evento para cada ação e


ouvidor de ação é executada começando com o(s) ouvidor(es) de ação e
então a chamada do método de ação.

6 - Apresentação da resposta.

11
12
Um tema central do design de aplicações web é a separação da
apresentação e lógica de negócios. JSF utiliza beans para conseguir
esta separação.

Páginas JSF referem-se a propriedades de beans, e a lógica do


programa está contida no código de implementação do bean. Porque o
bean é tão fundamental para a programação JSF, nós discutiremos em
detalhes neste capítulo.

13
Managed beans são componentes JavaBeans que podem ser
registrados no JSF.
Em outras palavras, managed beans é um java bean gerenciado pelo
framework JSF.

O managed bean contém métodos getters e setters, lógica ou até um


backing bean (um bean que contém todos os valores de um formulário
HTML).

Managed beans funcionam como um Model para um componente de


UI.

Managed bean pode ser acessado de uma página JSF.

14
Em JSF 1.2 um managed bean tem que ser registrado em um arquivo
de configuração JSF como o faces-config.xml

15
Em JSF 2.0, managed beans podem ser facilmente registrados
utilizando anotações.
Esse método mantém beans e suas configurações somente em um
lugar, tornando fácil de se gerenciar.

16
17
18
A aplicação "clássica" para JavaBeans é um construtor de interface do
usuário. Uma janela de paleta na ferramenta contém beans de
componentes, tais como campos de texto, barras, caixas de seleção, e
assim por diante. Em vez de escrever código Java, você usa a interface
gráfica para arrastar e soltar beans da paleta para um formulário.
Depois, você pode personalizar o bean.

19
No contexto da JSF, beans armazenam o estado de páginas da web.
Criação e manipulação de beans está sob o controle da aplicação JSF.
A implementação JSF faz o seguinte:

• Cria e elimina beans, conforme necessário (daí o termo "managed


beans");
• Lê as propriedades do bean ao exibir uma página web;
• Define as propriedades do bean, quando um formulário é submetido.

20
Você pode omitir o atributo name na anotação @ManagedBean. Nesse
caso, o nome do bean é derivado do nome da classe, transformando a
primeira letra em minúscula. Por exemplo, se você omitir (name =
"user") no exemplo acima, o nome do bean se torna userBean.

A anotação @ManagedBean está no pacote javax.faces.bean. Java EE


6 define uma outra anotação @ManagedBean no pacote
javax.annotation que não funciona com JSF.

21
Quando uma expressão com o nome user é encontrada pela primeira
vez, a implementação JSF constrói um objeto da classe UserBean. O
objeto permanece vivo na sessão, isto é, para todas as solicitações que
se originam do mesmo cliente. Durante toda a sessão, bean user faz
referência ao objeto previamente construído. Em um determinado
ponto no tempo, diferentes sessões que pertencem a diferentes
clientes podem estar ativas no servidor. Cada uma delas tem seu
próprio objeto UserBean.

22
Quando uma expressão com o nome user é encontrada pela primeira
vez, a implementação JSF constrói um objeto da classe UserBean. O
objeto permanece vivo na sessão, isto é, para todas as solicitações que
se originam do mesmo cliente. Durante toda a sessão, bean user faz
referência ao objeto previamente construído. Em um determinado
ponto no tempo, diferentes sessões que pertencem a diferentes
clientes podem estar ativas no servidor. Cada uma delas tem seu
próprio objeto UserBean.

23
Definindo propriedades com padrões de nomenclatura é simples.
Considere o seguinte par de métodos:

T public getFoo ()
public void setFoo (T newValue)

O par corresponde a uma propriedade de leitura e escrita com o tipo T


e nome foo. Se você tiver apenas o primeiro método, a propriedade é
somente leitura. Se você tiver apenas o segundo método, a
propriedade é somente gravação.

Para propriedades do tipo booleanas, você tem uma escolha de


prefixos para o método que lê a propriedade. Ambos

public boolean isConnected() e


public boolean getConnected()

São nomes válidos para a propriedade connected.

24
Quando a implementação JSF renderiza a página, ele chama o método
getName() do objeto user. As expressões podem ser utilizadas tanto
para a leitura e
escrita de uma propriedade. Considere este componente de entrada:

<h: inputText value = "# {user.name}" />

Quando a execução JSF renderiza o componente, ele chama a


propriedade getter. Quando o usuário envia a página, a implementação
JSF invoca a propriedade setter.

25
Alguns ambientes de desenvolvimento visual JSF utilizam backing
bean. Estes ambientes geram automaticamente propriedade getters e
setters para todos os componentes que são arrastados para um
formulário.

Quando você usa um backing bean, você precisa conectar os


componentes no formulário para o Bean. Você pode usar o atributo de
vinculação com esta finalidade: <h:inputText binding="#
{quizForm.answerComponent} " ... />

26
JSF foi pioneira no conceito de "managed beans" em aplicações web.
No entanto, managed beans JSF são bastante limitados. A JSR 299
("Contextos e Injeção de Dependência", muitas vezes abreviado como
CDI) define um modelo mais flexível para Beans que são gerenciados
pelo servidor de aplicativos. Esses Beans são ligados a um contexto.
CDI especifica mecanismos para injetar Beans, interceptar e decorar
chamadas de método. Porque CDI é um mecanismo muito mais
poderoso do que JSF managed beans, faz sentido usar Beans CDI
caso você implante o aplicativo em um servidor de aplicativos Java EE.

Aqui, a anotação @SessionScoped é a do pacote


javax.enterprise.context, não o pacote javax.faces.bean. Note que os
Beans CDI com escopo de sessão deve implementar a interface
Serializable

27
Quando você define um bean, você precisa especificar o seu escopo.
Três escopos são comuns a JSF e CDI:
• Sessão
• Requisição
• Aplicação

JSF 2.0 adiciona um escopo view e escopos personalizados. Estes não


são suportados no CDI, que em vez disso tem um escopo de
conversação muito mais útil. No JSF 2.0, você pode usar anotações,
como as seguintes, para a definição de escopos:
@SessionScoped
@RequestScoped
@ApplicationScoped

28
Rastreamento de sessão com cookies é completamente transparente
para o desenvolvedor web, e as tags JSF executam automaticamente a
reescrita de URL se um cliente não usa cookies.

O escopo de sessão é criado a partir do momento que uma sessão é


criada e vive até o término da sessão. A sessão termina se a aplicação
chamar o método invalidate() no objeto HttpSession, ou se ela expirar.

29
30
Tudo começa quando uma solicitação HTTP é submetida e termina
após a resposta é enviada de volta para o cliente.

Se você colocar um bean gerenciado no escopo da solicitação, uma


nova instância é criado com cada solicitação. Vale a pena considerar
esse escopo, se você está preocupado com o custo de
armazenamento escopo de sessão.

Só beans que estão no escopo da request são single-thread e,


portanto, inerentemente threadsafe. Talvez surpreendentemente, beans
de sessão não são-single-thread. Por exemplo, um usuário pode enviar
simultaneamente requisições de várias janelas do navegador. Cada
resposta é processada por uma thread diferente. Se você precisa de
que seus beans armazenados no escopo da sessão sejam thread-safe,
você deve fornecer mecanismos para isso.

31
Managed Beans são inseridos no escopo da aplicação se um único
bean deve ser compartilhado entre todas as instâncias de uma
aplicação web. O bean é construído quando é solicitado pela primeira
vez por qualquer usuário da aplicação, e se mantém vivo até que a
aplicação web seja removida do servidor.

O atributo eager é uma novidade da versão do JSF 2.0

32
Um escopo de conversação persiste ao longo de um conjunto de
páginas relacionadas. Isto proporciona a persistência de dados até que
um determinado objetivo seja atingido, sem a necessidade de
armazenar os dados na sessão. A conversa está vinculada a uma
página do navegador específico ou aba. Uma única sessão pode ter
várias conversas em páginas diferentes. Este é um requisito importante
na prática. Os usuários muitas vezes criam novas abas para que eles
possam explorar duas partes da aplicação em paralelo.

33
Exemplo de uso do escopo de conversação

34
O escopo de View foi adicionado no JSF 2.0. Um bean nesse escopo
persiste enquanto a mesma página JSF é reexibida. Assim que o
usuário navega para uma página diferente, o bean fica fora do escopo.
Esse escopo é particularmente útil para aplicações Ajax.

35
Um escopo é simplesmente uma Map que liga nomes aos objetos. O
que distingue um escopo de outro é o tempo de vida da Map. Os
tempos de vida dos quatro escopos JSF (sessão, aplicação, view, e
requisição) são geridos pela implementação JSF. A partir do JSF 2.0,
você pode fornecer escopos personalizados cujo tempo de vida você
pode gerenciar.

36
37
A anotação @PostConstruct é útil para os beans que precisam obter
dados para exibição em uma página. Outro uso comum é para beans,
que estabelecem conexões com recursos externos, tais como bancos
de dados.

38
39
40
São muitos os pontos de melhoria, mas gostaremos de ressaltar
alguns, principalmente no que concerne à evolução/futuro da
plataforma. Ficamos muito tempo parados no JSF 1.2 e não vimos
progresso na especificação. Contudo, parece que o jogo mudou no JSF
2.0.

41
JSF sempre foi considerado um framework com problemas graves de
desempenho desde suas primeiras versões (RI 1.0/1.1). No entanto,
após o lançamento do JSF 1.2 muitos dos problemas de performance
foram resolvidos graças ao talentoso time de desenvolvedores da
Mojarra (RI). Mas ainda assim, devido a limitações de design na
especificação do JSF 1.2, o time de desenvolvedores sempre teve
dificuldades para escrever código performático. Somente com a
especificação do JSF 2 é que tornou-se possível escrever código
desde o início com performance em mente.

O número de componentes tem crescido a cada dia devido a facilidade


de se implementar componentes no JSF 2.

42
Outro ponto interessante é que com o sucesso do JSF 2 as empresas
mantenedoras tem diminuído o suporte e a implementação de novos
componentes JSF1.2, e, provavelmente, em médio prazo será ainda
mais raro obter correções e melhorias para esses componentes de
forma gratuita.

Há muitas funcionalidades interessantes na especificação e ver o JSF


tentar se alinhar mostra cada vez mais a preocupação da tecnologia
em melhorar a User Experience.

43
44
45
46
47
A tag form cria um elemento de formulário HTML. Formulários JSF
usam a técnica de "post-back" para enviar os dados do formulário de
volta para a página que contém o formulário.

Também é necessária a utilização do método POST e não é possível


utilizar o método GET para formulários gerados por esta tag. Se seu
aplicativo requer o uso do método GET para o envio do formulário, as
opções incluem o uso de formulários HTML simples ou utilizar a tag
outputLink para gerar hiperlinks dinâmicos.

48
Estamos definindo um formulário simples contendo um inputText e
commandButton. O commandButton irá enviar o formulário quando
clicado pelo usuário. Há também uma outputText que irá exibir a
entrada introduzida pelo usuário.

49
A tag commandButton cria um botão que pode ser associado a um
backing bean ou uma classe ActionListener para fins de manipulação
de eventos. O valor da exibição do botão pode também ser obtido a
partir de um pacote de mensagem que suporta internacionalização
(I18N).

50
A tag commandLink cria uma link HTML que se comporta como um
submit de um formulário e que pode ser associado a um backing bean
ou uma classe ActionListener para fins de manipulação de eventos. O
valor de exibição pode também ser obtido a partir de um pacote de
mensagem com suporte a internacionalização (I18N).

51
52
53
54
55
56
A tag outputText cria um texto básico em sua página JSF. Você pode
personalizar a aparência do texto usando estilos CSS, caso em que o
texto gerado é envolto em um elemento span HTML. Você também
pode escapar do texto processado se ele contiver caracteres HTML e
XML sensíveis.

57
58
A tag outputLabel cria um HTML elemento "label". Ele permite que você
personalize a aparência usando CSS. O componente outputLabel está
associado a um outro componente, através do atributo “for”.

O outro componente deve ser criado antes do componente outputLabel


quando a página JSF é processada. Note-se a utilização do container
panelGroup no exemplo acima. O componente panelGroup renderiza
seus filhos, permitindo que o componente outputLabel localize o
componente inputText na hora de renderizar o elemento.

59
60
A tag outputLink cria um link HTML com um atributo "href".

O nome de exibição pode também ser obtido a partir de um pacote de


mensagem com suporte a internacionalização (I18N). Esta tag facilita a
construção de hiperlinks HTML.

Você pode colocar a tag outputText ou graphicImage, por exemplo,


dentro da tag outputLink para definir o texto do hiperlink ou o valor da
imagem.

61
A tag OutputFormat cria o texto formatado e permite que você
personalize a aparência deste texto usando CSS. Texto parametrizado
é um texto composto que contém os valores reservado para serem
substituído por valores reais no tempo de processamento.

62
63
64
A tag selectBooleanCheckbox cria um elemento de entrada HTML do
tipo "checkbox". Este componente é projetado para situações em que
você deseja exibir uma opção para o usuário que pode ser ativado ou
desativado, como um “Lembrar senha" em um formulário de login.

65
A tag SelectManyCheckbox renderiza uma lista de caixas de seleção
HTML. Este componente é projetado para situações em que você
deseja exibir uma lista de opções para o usuário que não são
mutuamente exclusivas, como uma lista de opções. Este componente
suporta dois layouts: "lineDirection" (na horizontal, o layout padrão) e
"pageDirection" (vertical).

66
A tag SelectManyMenu cria um elemento HTML “select" com os
atributos “multiple" e “size" definido como 1. Este componente é
projetado para situações em que você deseja exibir uma lista de itens
de menu para o usuário que permite a seleção de múltiplas opções
usando um menu que exibe um item de cada vez. A principal diferença
entre listas de seleção e menus em JSF é o atributo "size". Menus
sempre tem um tamanho de um elemento, enquanto que as listas
podem ter um tamanho variável.

67
68
A tag selectOneListbox cria um elemento HTML “select" de qualquer
tamanho, sem o atributo “multiple". Este componente é projetado para
situações em que você deseja exibir uma lista de seleção única de
opções para o usuário em uma lista que exibe vários itens de uma vez.
Se você não especificar o tamanho, todas as opções disponíveis são
mostrados. A principal diferença entre listas de seleção e menus em
JSF é o atributo "size". Menus sempre tem um tamanho de um,
enquanto que as listas podem ter um tamanho variável.

69
A tag SelectOneRadio cria uma tabela HTML de elementos do tipo
"radio". Este componente é projetado para situações em que você
deseja exibir uma lista de opções mutuamente exclusivas para o
usuário como um conjunto de botões de “radio”. Como a tag
selectManyCheckbox, esta tag suporta dois modos de layout:
lineDirection (horizontal, o padrão) e pageDirection (vertical).

70
71
72
73
74
75
Quando você usa um backing bean, você precisa conectar os
componentes do formulário com o bean. Você pode usar o atributo
binding para isso.

Todos os componentes possuem o atributo binding e pode ser usado


para construir essa ligação do componente com o backing bean.

76
Um instância FacesContext é associada a uma requisição no início do
processamento da requisição, através da chamada de método
getFacesContext() da classe FacesContextFactory associada com a
aplicação web. Essa instância se mantém ativa até que o método
release() seja chamado, depois disso nenhuma referência a essa
instância é mais permitido.

Enquanto a instância do FacesContext está ativa, ela nunca será


referenciada por nenhuma outra thread a não ser a thread que está
processando a requisição.

77
78
79
80
Eventos de alteração de valor são disparados por componentes como
h:inputText, h:selectOneRadio, e h:selectManyMenu - quando o
conteúdo do valor do componente for alterado.

Eventos de ação são disparados por fontes de Ação, como por


exemplo, h:commandButton e h:commandLink-quando o botão ou link
é ativado. Eventos de Fase são rotineiramente disparados pelo ciclo de
vida do JSF. JSF 2.0 adiciona um grande número de eventos do
sistema.

81
82
Componentes em uma aplicação web, muitas vezes dependem um do
outro, você pode manter os componentes dependentes em sincronia
com eventos de alteração de valor

83
Como todos os listeners de alteração de valor, o evento de alteração de
valor é passado como argumento. O listener usa esse evento para
acessar o novo valor do componente.

Mais uma coisa é importante sobre este exemplo. Observe que foi
adicionado um atributo onchange cujo valor é submit() a tag
h:selectOneMenu. Definir esse atributo significa que o JavaScript irá
submeter o form toda vez que alguém alterar o valor do menu

A implementação JSF manipula todos os eventos do servidor. Se você


tirar o atributo onchange, o formulário não será submetido quando o
item de menu for alterado, o que significa que o ciclo de vida JSF
nunca será chamado, nosso listener de alteração de valor nunca será
chamado.

84
É importante distinguir entre listeners e actions. Em suma, actions são
projetadas para a lógica de negócios e participam da manipulação de
navegação, enquanto os listeners normalmente executam lógica de
interface de usuário e não participam na manipulação de navegação.

85
As tags têm uma vantagem sobre os atributos: Tags permitem anexar
vários listeners para um único componente.

86
Esses eventos são tratados pelos listeners de fase. Ao contrário de
listeners de ação que você conecta a componentes individuais, um
listener de fase está ligado à raiz da view.

Alternativamente, você pode especificar os listeners de fase de forma


global em um arquivo de configuração do JSF.

Os listeners são chamados na ordem em que eles são especificados


no arquivo de configuração.

87
O método getPhaseId() diz a implementação JSF quando é para
entregar eventos de fase listener, o método getPhaseId() poderia
retornar PhaseId.APPLY_REQUEST_VALUES. Nesse caso,
beforePhase() e afterPhase() seriam chamados uma vez por ciclo de
vida: antes e depois da fase Apply Request Values.

Você também pode especificar PhaseId.ANY_PHASE, o que significa


todas as fases, os métodos beforePhase() e afterPhase() do seu
listener de fase serão chamados seis vezes por ciclo de vida: uma vez
cada um para cada fase do ciclo de vida.

88
JSF 2.0 introduz um sistema de notificação em que os componentes
individuais, bem como a implementação JSF notifica os listeners de
muitos eventos interessantes. A Tabela acima lista os eventos do
sistema JSF.

89
Considere o que acontece quando o usuário de uma aplicação web
preenche uma página web. O usuário pode preencher os campos de
texto, clicar em botões, ou selecionar entradas de uma lista. Todas
estas edições acontecem dentro do navegador do usuário. Quando o
usuário clica em um botão que envia os dados do formulário, as
alterações são transmitidas para o servidor.

90
91
Em resumo, aqui estão os passos realizados sempre que o usuário
clica em um botão de comando cujo atributo action é uma método de
expressão:

1. O bean especificado é recuperado.


2. O método de referência é chamado e retorna uma String como
resultado.
3. A String é transformada em uma View ID.
4. A página correspondente ao View ID é exibida.

92
Esta regra estabelece que o resultado para o success navega para
/welcome.xhtml se foi originado a partir do /index.xhtml.

As view ID começam com a /. Se você usar o mapeamento de


extensão (como um sufixo .faces), a extensão deve coincidir com a
extensão de arquivo (como . xhtml), não a extensão de URL.

93
O redirecionando é um processo mais lento porque é envolvida uma
outra ida e volta para o navegador.

Em uma regra de navegação, você adiciona um elemento de


redirecionamento após to-view-id:

<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/success.xhtml</to-view-id>
<redirect/>
</navigation-case>

94
95
96
97
98
O manipulador de navegação retira os parâmetros de resultado, calcula
o View ID de destino, e acrescenta os parâmetros. Neste exemplo, a
identificação de exibição de destino é /index.xhtml?q=1

Utilizando o parâmetro includeViewParams todos os parâmetros de


exibição consulta são inseridos.

99
A partir do JSF 2.0, você pode fornecer um elemento if que se ativa a
um caso de navegação somente quando a condição for cumprida.
Forneça uma expressão de booleana para a condição.

100
As interfaces de usuário são normalmente o componente mais volátil
de um aplicativo web durante o desenvolvimento, e muitas vezes são
compostos de código frágil que é difícil de mudar, tornando interfaces
elementos difíceis para se desenvolver.

101
102
103
A maioria das aplicações web seguem um padrão semelhante, em que
todas as páginas têm um layout e um estilo comum. Por exemplo,
normalmente as páginas têm o mesmo cabeçalho, rodapé, e barras
laterais. Facelets permite encapsular tudo em um modelo, de modo que
você pode atualizar o visual do seu site, fazendo alterações no modelo,
e não nas páginas individuais.

A aplicação planetas tem um total de 10 páginas: a página de login, a


página de boas vindas, e uma página para cada um dos planetas.
Todas essas páginas compartilham um layout comum, com um
cabeçalho no topo, uma barra lateral à esquerda, e uma área de
conteúdo à direita da barra lateral. As páginas também partilham
alguns conteúdos e um CSS.

104
O modelo usa a tag ui:insert quatro vezes, para inserir:
• O título da janela
• O título
• A barra lateral esquerda
• O conteúdo principal

O modelo também insere uma folha de estilo na página. A folha de


estilo define o layout para o título, a barra lateral, e o conteúdo
principal.

105
106
107
Decorators são uma abordagem mais centrada no conteúdo.

108
Observe a tag <ui:insert />. Insere todas os elementos internos da tag
<ui:decorate>.

A diferença entre ui:composition e ui:decorate é principalmente


conceitual. Você pode conseguir os mesmos efeitos com qualquer uma
das tag. Facelets simplesmente os considera como construções
complementares: ui:composition retira os conteúdos externos,
enquanto ui:decorate não (e, portanto, requer um ui:composition no
modelo).

109
Quando as aplicações possuem telas complexas, com grande
quantidade de conteúdo, não é interessante recarregar uma página
inteira só para modificar uma pequena parte da tela.

A versão 2 do JSF, diferentemente das anteriores, oferece suporte


nativo a AJAX.

Para cada evento keyup no inputText, o JSF faz uma chamada Ajax
para o servidor, e processa o valor da entrada. Quando a chamada do
Ajax retorna, o JSF renderiza o componente someOtherComponentId

110
111
112
Em qualquer pedido Ajax, você especifica um conjunto de
componentes que o JSF executa, e um outro conjunto de componentes
que serão renderizados.

113
Isso normalmente leva poucas linhas de XML em um arquivo XHTML, e
talvez algumas linhas de Java em um bean gerenciado para
implementar a maioria dos casos de uso Ajax.

Você associa uma chamada Ajax com um evento, como keyup ou blur,
disparado por um componente específico. Em seguida, você especifica
os componentes que você deseja executar, e os componentes que
você deseja renderizar.

114
Novamente, se não escolhermos explicitamente o evento que vai
disparar as requisições AJAX, o JSF assumirá o evento padrão de cada
componente. O padrão dos componentes <h:inputText> e
<h:inputSecret> é onchange. Já o padrão do componente
<h:commandButton> é onclick.

Podemos explicitar o evento que deve disparar as requisições AJAX


para um determinado grupo de componentes da mesma forma como
fizemos anteriormente.

115
Podemos associar um método a uma requisição AJAX. Esse método
será executado durante o processamento dessa requisição no servidor.
Mais especificamente, ele será executado na fase Invoke Application.
Essa associação é realizada através do atributo listener da tag
<f:ajax>.

No exemplo acima, as requisições AJAX realizadas através do botão


“Salva” foram associadas ao método salva() do managed bean
produtoBean.

116
Podemos alterar o código do formulário anterior para utilizar a palavra
especial @form no lugar do identificador do formulário.

<h:form id="formulario-login ">


<h:inputText />
<h:inputSecret />
<h:commandButton value="Enviar">
<f:ajax event="click" execute="@form"/>
</h:commandButton>
</h:form>

117
Quando um usuário preenche um formulário, os valores preenchidos
são enviados para uma aplicação. De acordo com o HTTP, protocolo
de comunicação utilizado entre os navegadores e as aplicações web,
esses dados não possuem tipagem. Eles são tratados como texto puro.
Dessa forma,
quando uma aplicação recebe valores preenchidos em formulários
HTML, ela precisa realizar a conversão dos dados que deseja tratar de
forma específica.

118
Para facilitar o trabalho de desenvolvimento de uma aplicação, o JSF
define um conjunto de conversores padrão. Alguns desses conversores
são aplicados automaticamente. Outros conversores são aplicados
apenas se forem explicitamente indicados.

119
120
Alguns conversores padrão podem ou precisam usar informações
adicionais para realizar a conversão de dados. As tags
<f:convertNumber> e <f:convertDateTime> são usadas para transmitir
informações aos conversores de números (java.lang.Number) e datas
(java.util.Date), respectivamente.

121
Alguns conversores padrão podem ou precisam usar informações
adicionais para realizar a conversão de dados. As tags
<f:convertNumber> e <f:convertDateTime> são usadas para transmitir
informações aos conversores de números (java.lang.Number) e datas
(java.util.Date), respectivamente.

Para mais detalhes sobre o uso do atributo pattern, consulte a página


http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.ht
ml.

122
Eventualmente, as informações preenchidas pelos usuários em
formulários não são adequadas, impedindo a conversão dos dados.
Nesses casos, geralmente, desejamos apresentar mensagens
relacionadas aos erros no preenchimento das informações.

Para exibir erros relacionados a um determinado campo, podemos


utilizar o componente <h:message>. Esse componente deve ser
associado ao campo correspondente aos erros que desejamos exibir.
Para estabelecer essa ligação, devemos definir o valor do atributo for
do componente <h:message>
igual ao valor do atributo id do campo em questão.

123
Como vimos, um dado enviado através de uma requisição HTTP chega
na aplicação no formato de texto. O processo de conversão consiste
em transformar esse texto em algum tipo específico do Java. Após a
conversão, podemos verificar se os valores obtidos respeitam
determinadas restrições impostas pelas regras da aplicação. Por
exemplo, considere um campo para o usuário digitar sua idade. Como
discutido anteriormente, o valor digitado será tratado como texto até
chegar na aplicação. Em seguida, esse dado será convertido para um
tipo numérico do Java (como int ou long por exemplo).

Dessa forma, depois da conversão dos dados, mais uma etapa é


necessária para que essa verificação seja realizada. Essa etapa é
conhecida como validação.

124
O validador <f:validateDoubleRange> funciona de forma análoga ao
<f:validateLongRange>. Ele é utilizado para verificar se um valor
numérico real pertence a um determinado intervalo de números. No
exemplo abaixo, o validador verificará se o valor da propriedade preco
do managed bean testeBean está entre 20.57 e 200.56.

O validador <f:validateLength> verifica se uma string possui uma


quantidade mínima ou máxima de caracteres. Veja o exemplo. Nesse
exemplo, a restrição imposta é a de que a propriedade nome do
managed bean testeBean seja uma string com pelo menos 6 e no
máximo 20 caracteres.

125
O validador <f:validateRegex> é usado para verificar se um texto
respeita uma determinada expressão regular. No exemplo abaixo, o
validador verificará se a propriedade codigo tem pelo menos 6 e no
máximo 20 caracteres, além de ser formada apenas por letras.

126
Uma nova abordagem para definir validações foi adicionada no JSF 2.
A ideia é declarar as regras de validação nas classes do modelo ao
invés de inseri-las nos arquivos XHTML que definem as telas.

A grande vantagem das validações definidas nas classes do modelo é


que elas podem ser utilizadas em diversas partes da aplicação. Esse
novo recurso é chamado Bean Validation.

127
As validações definidas através das anotações da especificação bean
validation são aplicadas automaticamente pelo JSF. As mensagens de
erro referentes a essas validações são automaticamente
acrescentadas no contexto do processamento da requisição
correspondente.

128
As validações definidas através das anotações da especificação bean
validation são aplicadas automaticamente pelo JSF. As mensagens de
erro referentes a essas validações são automaticamente
acrescentadas no contexto do processamento da requisição
correspondente.

129
As validações definidas através das anotações da especificação bean
validation são aplicadas automaticamente pelo JSF. As mensagens de
erro referentes a essas validações são automaticamente
acrescentadas no contexto do processamento da requisição
correspondente.

130
No exemplo acima, a mensagem de erro de validação está definida de
maneira fixa. Pode ser mais apropriado defini-la em um arquivo de
mensagens. Nesse caso, devemos criar um arquivo chamado
ValidationMessages.properties no classpath da aplicação. No exemplo
abaixo, a mensagem “O nome do funcionário não pode ser nulo” está
associada à chave br.com.cbds.Funcionario.nome.

131
Se os conversores padrão não forem suficientes para atender as
necessidades de uma aplicação, podemos criar os nossos próprios
conversores. Considere uma aplicação que armazena números de
telefones internacionais. Esses números serão modelados pela
seguinte classe.

132
O primeiro passo para implementar um conversor JSF é criar uma
classe que implementa a interface javax.faces.convert.Converter.
Nessa classe, devemos adicionar a anotação @FacesConverter para
indicar a classe associada a esse conversor.

133
A criação de um validador é análoga à criação de um conversor.
Precisamos criar uma classe que implemente a interface
javax.faces.validator.Validator. Essa interface define um único método,
o validate(). Além disso, a classe também precisa ser anotada com
@FacesValidator.

Considere um formulário HTML que possui uma caixa de texto para o


usuário digitar um número primo. Um número primo é um número
natural maior do que 1 cujos únicos divisores positivos são 1 e ele
mesmo. Essa caixa de texto está associada a uma propriedade do tipo
long em um managed bean.

134
Para realizar a validação de um determinado dado, informações
adicionais podem ser necessárias. Por exemplo, considere o caso em
que precisamos verificar se uma data escolhida por um usuário
pertence a um determinado intervalo. Nesse caso, precisamos de duas
informações adicionais: as datas de início e fim do intervalo.

Para definir um atributo de um componente visual, podemos usar a tag


<f:attribute>. Essa tag possui dois parâmetros (name e value), que são
usados para definir o nome e o valor desse atributo.

135
Você não pode exibir uma árvore ou um calendário tabular como um
componente. Felizmente, JSF torna possível a construção de
componentes personalizados com comportamento ricos.

136
Iremos fazer um Spinner para ilustrar os passos para construção de um
componente customizado.

137
Por convenção, o nome da classe componente tem um exemplo prefixo
UI, UISpinner. Classes de componentes pode delegar a codificação e
decodificação para um renderizador separado. Utilizando
renderizadores diferentes, você pode suportar vários clientes, como
navegadores web e telefones celulares.

138
Essa classe define mais de 40 métodos abstratos, de modo que você
vai querer estender uma classe existente que os implementa.

139
• UIOutput, se o componente apresenta um valor, mas não permite
que o usuário edite-o;

• UIInput, se o seu componente lê um valor do usuário (como o


spinner);

• UICommand, se o componente produz ações semelhantes a um


botão de comando ou link

140
O Spinner permite que você digite um número em um campo de texto,
ou digitando-o diretamente no campo ou pela ativação de um botão de
incremento ou decremento. A figura acima mostra um aplicativo que
usa dois spinners, um para o mês e outro para o ano da data de
validade do cartão de crédito.

141
O atributos minimum e maximum permitem que você atribua um
intervalo de valores válidos, por exemplo, o spinner mês tem um
mínimo de 1 e um máximo de 12. Você também pode limitar o tamanho
do campo de texto do spinner com o atributo size. Nas seções
seguintes, vamos implementar o componente UISpinner que lida com
as responsabilidades de codificação e decodificação.

142
O atributos minimum e maximum permitem que você atribua um
intervalo de valores válidos, por exemplo, o spinner mês tem um
mínimo de 1 e um máximo de 12. Você também pode limitar o tamanho
do campo de texto do spinner com o atributo size. Nas seções
seguintes, vamos implementar o componente UISpinner que lida com
as responsabilidades de codificação e decodificação.

143
Os componentes podem fazer sua própria codificação, ou podem
delegar codificação para um renderizador separado. Esta última é a
abordagem mais elegante, pois ela permite que você conecte diferente
renderizadores diferente de HTML.

No entanto, para simplificar, vamos começar com um Spinner que


renderiza ele mesmo.

144
Para componentes simples, como o nosso Spinner, que não tem filhos,
você não precisa implementar encodeChildren(). Em razão disso, toda
a nossa codificação acontece dentro do método encodeBegin().

145
Para entender o processo de decodificação, tenha em mente como
uma aplicação web funciona. O servidor envia um formulário HTML
para o navegador.

Quando o usuário submete o formulário, o navegador envia uma


solicitação POST que consiste em pares de nome/valor.

146
147
148
149
150
Além de implementar uma classe de componente, você também
precisa fornecer um arquivo descritor que especifica como as tags de
componentes personalizados podem ser usados em uma página JSF.

Lembre-se que o nome do arquivo deve terminar em taglib.xml, por


exemplo cbds.taglib.xml.

151
152
153
154
155
RichFaces é uma biblioteca de componentes ricos para Java Server
Faces construídos sobre um framework open source avançado
(Ajax4jsf). Ele permite fácil integração de recursos do AJAX para
desenvolvimento de aplicativos de negócios de nível empresarial.

RichFaces enriquece o framework Ajax4jsf de duas maneiras


importantes. Primeiro, ele expande o número de componentes para uso
visual. Em segundo lugar, ele implementa totalmente o recurso
skinnability do quadro Ajax4jsf incluindo um grande número de skins
pré-definidos. Usando skinnability, é muito mais fácil gerenciar o look-
and-feel de um aplicativo.

156
a4j:support é o principal componente e mais importante na biblioteca
RichFaces. Permite adicionar uma capacidade Ajax aos componentes
não-ajax existentes. Todos os outros componentes Ajax são baseados
nos mesmos princípios que o a4j:súpport.
a4j:support deve ser anexado a um filho direto do componente JSF que
tem de ser ajaxified. Os atributos-chave são ‘event' e 'reRender'.

O exemplo acima mostra como o valor do componente outputText é


alterada quando um usuário está digitando no campo de entrada:

157
a4j:commandButton é semelhante ao padrão h:commandButton, mas
produz um pedido Ajax com uma nova atualização parcial de página. O
atributo 'reRender' aponta para o componente que deve ser re-
processado na árvore de componentes e atualizado no DOM do
navegador depois de que uma resposta
Ajax é concluída.

O exemplo acima mostra como a mensagem de saudação é mostrado


na tela sem atualizar a página inteira.

158
a4j:commandLink é semelhante ao padrão h:commandLink, mas
produz um pedido Ajax com nova atualização parcial de página. O
atributo 'reRender' aponta para o componente que deve ser re-
processado na árvore de componentes e atualizado no DOM
navegador após a resposta Ajax estiver completa.

O exemplo acima mostra como a mensagem de saudação é mostrada


na tela sem atualizar a página inteira.

159
O componente a4j:jsFunction é muito semelhante ao
a4j:commandButton, mas permite realizar um pedido Ajax de um
código Javascript diretamente. O componente envia um pedido,
utilizando uma abordagem padrão JSF, de modo que o form JSF é
necessário.

O exemplo acima mostra como a parte de uma página é re-processado


quando um usuário passa o mouse sobre os nomes.

160
O <a4j:push> realizar periodicamente pedido AJAX para o servidor,
para simular dados 'push'.
A principal diferença entre <a4j:push> e componentes <a4j:poll> é que
<a4j:push> faz pedido para o mínimo de código apenas (e não a árvore
JSF), a fim de verificar a presença de mensagens na fila. Se a
mensagem existe o pedido completo será executado.

Atributo ‘interval' especifica o intervalo em milissegundos para


solicitação de envio de chamada. Exemplo simples de uso:

161
O componente a4j:status é um indicador de uma solicitação Ajax. Tem
dois estados - start e stop. O estado start indica que uma solicitação
Ajax está em andamento. Quando Ajax a resposta retorna, o
componente muda para o estágio de stop.

162
O componente rich:ajaxValidator é um componente projetado para
fornecer validação ajax dentro das entradas. Ele é projetado como um
componente a4j:support mas ignora todo o processamento JSF exceto
validação.

163
A partir da versão 3.2.2 fornece suporte para as restrições baseadas
em modelos definidos usando o Hibernate Validator. Assim, é possível
usar Hibernate validator.

O componente rich:beanValidator deve ser definido da mesma forma


como todos os validadores JSF. Olhe através do exemplo acima.

164
rich:calendar permite selecionar a data utilizando elementos de
calendário nas páginas. É possível usar o componente em um pop-up e
código embutido. Em um modo pop-up o Calendar é inicialmente
processado como entrada para a data e botão do lado direito para
chamar o popup. No caso de um modo inline, o calendário mensal está
localizado em uma página.

165
O componente fornece elemento combo box editável na página.
Combo Box é uma versão simplificada do componente SuggestionBox,
que usa sugestões do cliente.

166
O Componente Editor oferece a possibilidade de usar o widget
tinyMCE.

167
O componente InputNumberSlider é altamente personalizável e é
usado para definir a entrada numérica em um determinado intervalo.
Você pode usar um controle slider ou simplesmente digitar um texto em
um campo de entrada.

168
O componente InputNumberSpinner é altamente personalizado e é
usado para definir uma entrada numérica de um intervalo. Um usuário
pode usar um controle spinner ou simplesmente digitar um texto em um
campo de entrada.

169
O Componente SuggestionBox adiciona a capacidade autocomplete
para o componente existente de entrada, como h:inputText ou
t:inputText. Use o atributo 'for', a fim de adicionar a capacidade de
autocomplete para ele.

170
RichFaces modalPanel é um container que bloqueia uma operação na
página base quando o painel modal é mostrado.
ModalPanel pode ser gerenciado com o componente
rich:componentControl.

Exemplo acima mostra o código que deve ser usado.

171
O componente Richfaces Panel Bar é um conjunto de painéis, quando
um painel é expandido, outros estão compactados. A demonstração a
seguir mostra o exemplo de uso para o componente.

172
TabPanel é usado para criar páginas de "guias". TabPanel pode ser
usado em 3 maneiras: usando atualização do lado do servidor "normal",
com atualização estilo "ajax", quando apenas a área do painel guia é
atualizado na página, e usando o tipo "cliente", sem qualquer interação
com o servidor . Note, que em caso de um "cliente“.

173
174
O componente rich:progressBar pode ser utilizado para exibir o
progresso de qualquer cliente ou o processo do lado do servidor.

O exemplo mostra barra de progresso onde consulta o servidor a cada


dois segundo para obter novo valor e atualizar a barra de progresso.

175
O componente tem uma lista a partir de um modelo e gera da mesma
forma que com <h:PanelGrid> para dados inline. Para definir
propriedades da grade e estilos, utilize as mesmas definições para
<h:panelGrid>.

176
O componente é projetado para fornecer a funcionalidade de paginação
da tabela usando solicitações de AJAX.

177
Tabela de dados tem colunas com função de filtragem. A maneira mais
simples de adicionar capacidade de filtragem é definir atributo filterBy
em uma coluna você queira filtrar.

178
Tabela de dados tem função integrada de classificação. A maneira mais
simples de adicionar capacidade de classificação é definir atributo
sortBy na coluna que você precisa que sejam classificáveis.

Neste exemplo, você poderia ver que as duas primeiras colunas são
ordenadas depois de um clique no cabeçalho correspondente.

179
DataTable permite mostrar dados tabulares. Além do padrão
<h:dataTable>, este componente permite estender colunas, flexibilidade
para cabeçalho e rodapé.

O exemplo a seguir mostra o componente dataTable:

180
181
O componente Tree é um componente que processa um controle de
árvore na página.
As características da Tree mais importantes são:

• Suporte nativo para as operações Ajax;


• Suporte para tipos "ajax", “client" e “server"
• Recursos de arrastar / soltar embutidos
• Look and Feel

182
Menu de contexto RichFaces é um componente que permite organizar
os menus de contexto hierárquicos semelhantes a uma aplicação
desktop.

Context Menu pode conter um conjunto de itens do menu, grupos de


menus e separadores de menu. A utilização destes componentes são
semelhantes ao uso do menu RichFaces DropDown.

183
Menu RichFaces Drop Down é um componente que permite organizar
o menu hierárquico semelhante a uma aplicação desktop.

184
185

Você também pode gostar