• Nenhum resultado encontrado

JSF. Versão 1.0. Apostila destinada ao curso com carga horária de 32 (trinta e duas) horas

N/A
N/A
Protected

Academic year: 2021

Share "JSF. Versão 1.0. Apostila destinada ao curso com carga horária de 32 (trinta e duas) horas"

Copied!
50
0
0

Texto

(1)

JSF

JavaServer Faces, é um Framework Web no padrão MVC como o objetivo de simplificar a construção de interfaces com o usuário para aplicações Java Web e fazer componente UI reutilizável fácil de implementar. Ao contrário da versão anterior da JSF, para a versão 2.0 quase tudo é declarado no arquivo faces-config.xml, além disso foi disponibilizada a permissão para usar anotações para navegação declarada, foi proposto o CDI Bean, o que torna o desenvolvimento mais fácil e mais rápido. JSF é uma excelente tecnologia JAVA no campo de desenvolvimento de aplicações Web. Este é o melhor lugar para passar conceitos JSF de maneira fácil e sequencial.

(2)

Sumário

1. JavaServer Faces...4

Características da JSF...4

2. Ajax com JSF...6

Enviar uma solicitação do Ajax...6

Renderizar a visão parcial...6

Processar a visão parcial...7

Outro Exemplo...8

3. Navegação...10

Navegação estática e dinâmica...10

Navegação Estática...11

Navegação Dinâmica...13

Outros detalhes...14

Especificar wild-cards...15

4. Facelets...16

Por que usar Facelets?...16

JSF 2 Templating com exemplo Facelets...17

1. Layout do modelo...17

2. Cabeçalho, Conteúdo e Rodapé...18

3. Utilizando template...20

5. Richfaces...22

Baixar os RichFaces...22

Adicionar as bibliotecas RichFaces para o projeto...22

Registrar o RichFaces no web.xml...22

managed bean...24

Demonstração dos Componentes...25

6. Primefaces...28

Características do PrimeFaces...28

Aplicativo Exemplo...28

7. Validação e Conversão...36

Fases do Ciclo de Vida...37

Sobre o atributo imediato...37

Um exemplo de trabalho...38

Conversão...38

Um conversor para cada ocasião...39

Conversores Personalizados...39

Validação...42

Validação e o Ciclo de Vida da JSF e seus componentes...42

Padrão de Validação...43

8. JSF e Spring...44

Lado Spring...44

Lado Java Server Faces...45

(3)

Apoio da API para a integração...46

9. JSF e Seam 2...47

Integração com JSF com EJB 3.0...47

Integração com AJAX...47

(4)

1. JavaServer Faces

Quais são as razões que iniciaram o projeto JSF e porque está tão falado estes dias? Há razões para o desenvolvimento de um novo framework apesar das muitas tecnologias já existentes como JSP, Servlets, Struts, entre outras. Ao desenvolver aplicações complexas Web baseadas em JSP, existe um problema enfrentado com essas tecnologias. Vejamos uma lista de alguns dos problemas enfrentados com as tecnologias anteriores, como JSP e

Servlets:

Codificação tediosa e repetitiva – Tecnologias anteriores, como JSP obrigam ao

programador realizar um monte de codificação tediosas e repetitivas.

Trabalhar diretamente com HTTP Request e HTTP Response – Usar estas

tecnologias os programadores trabalham diretamente com um solicitação HTTP e responde com objetos que manipula os registros. Por exemplo se o usuário submete o formulário de inscrição, em seguida, o programador escreve o código para obter os valores de cada elemento na forma em que uma variável realiza um posterior processamento. Quando existe a necessidade de recuperar os registros no banco de dados e, em seguida, mostrar no formulário de edição, então, neste caso, o programador escreve o código para recuperar o registro no banco de dados e em seguida, defina os valores nos formulários.

Não disponibilidade de IDE – É outro grande problema que afeta o custo

programadores produtividade e desenvolvimento dos aumentos projetos.

JSF muda esse cenário, fornecendo uma estrutura intuitiva para os desenvolvedores. Além

disso, JSP é uma especificação na qual muitos fornecedores estão desenvolvendo suas próprias implementações. Ambas as implementações livres e comerciais de JSF estão disponíveis estes dias. Pode-se escolher qualquer um deles com base em sua necessidade e orçamento.

Agora, em alguns dias os fornecedores de software estarão desenvolvendo uma IDE para o desenvolvimento de aplicativos baseados em JSF que é uma boa notícia para os iniciantes. Uma vez que familiarizado com os conceitos fundamentais do JSF pode-se iniciar o desenvolvimento de projetos de software usando qualquer IDE disponível no mercado. Estas mudanças permitem que o programador torne seu trabalho muito mais fácil.

JSF é um componente de estrutura orientada e dirigida a eventos para aplicações Web.

Facilita o desenvolvimento de GUI para aplicações Web. JSF permite que os programadores trabalhem com as interfaces extensíveis como botões, caixas de texto, caixas, entre outras. O programador escreve o código para um determinado evento, tais como o botão clicado. Isto faz com que a programação seja muito mais fácil e agora não há necessidade de escrever uma requisição e lógica de processamento de resposta.

Características da JSF

(5)

parte dos especialistas, mas para:

Autores de Páginas – Web designers possuem a experiência com arte gráfica.

Podem observar e sentir o projeto de aplicação web em HTML/JSP utilizando bibliotecas de marcas personalizadas de JSF.

Desenvolvedores de Aplicativos – podem integrar este projeto com componentes

de interface do usuário. objetos de programa, iniciadores de eventos, conversores, validadores.

Desenvolvedores de Componentes – podem construir componentes de interface

personalizados por causa da natureza extensível e personalizável da JSF. Podem criar seus próprios componentes diretamente de classes de componentes de interface do usuário ou estender os componentes padrão do JSF.

Arquitetos de Aplicativos – responsáveis pela criação de aplicativos Web. Definição

de navegação de página, garantindo escalabilidade para a aplicação, configurando registro o objeto bean são os principais pontos que um arquiteto de aplicativos trata.Fornecedores de Ferramentas – JSF é bem adequado para os fornecedores de

ferramentas, por exemplo, Sun Java Studio Creator é uma ferramenta de desenvolvimento de aplicativos, que fornecem ferramentas que tiram vantagens do JSF para criar interface do usuário mais fácil.

Muitos dos frameworks de desenvolvimento Web surgiram após uma fundamentada existência de Servlet e JSP. Struts surgiu como uma estrutura padrão de aplicativos Web. Tornou-se um framework padrão, porque chegou mais cedo no mercado e com as características necessárias, e os concorrentes tiveram que adicionar os recursos que faltavam para o Struts para obterem sucesso. Assim, tornou-se necessário para Java o advento de um novo framework padrão como um modelo de componente poderoso. Esta foi a principal razão para o desenvolvimento da tecnologia JSF. Então o principal propósito de desenvolver a JSF, foi criar uma coleção de APIs para os componentes de interface com a capacidade de gerir seus estados, manipular os eventos e validação.

Struts possui a opção de migrar para JSF. A opção mais simples é usar os componentes.

Isto permite tirar proveito de componentes de terceiros. A principal característica da JSF é a facilidade de uso. Torna o desenvolvimento de aplicações Web mais fácil e mais rápido do que em outros frameworks porque suporta componentes de interface do usuário e uma fácil manipulação de eventos. Possui componentes construído por terceiros que pode reduzir o custo de reescrever os elementos existentes e minimizar o tempo de desenvolvimento.

(6)

2. Ajax com JSF

Conforme colocado na capa desta a JSF 2.0 foi uma grande atualização sobre a JSF 1.2, uma das adições mais importantes para essa versão foi quanto ao suporte padrão para Ajax. Muitos conceitos e características são realizados ao longo do RichFaces. JSF vem com uma

tag que fornece a funcionalidade Ajax. A tag é chamada de <f:ajax>. Vamos dividir o uso

desta tag em três partes:

1. Enviar uma solicitação para o Ajax; 2. Renderizar a visão parcial;

3. Processar a visão parcial.

Enviar uma solicitação do Ajax

JSF vem com uma tag para enviar uma solicitação do Ajax. Esta tag é realmente um comportamento do lado cliente, e implica não ser utilizado isoladamente em uma página, é sempre adicionado uma tag filha (comportamento) para outro componente da interface do usuário (ou pode até mesmo envolver vários componentes). Usaremos um simples aplicativo para demonstrar essa utilização:

<h:form>

<h:panelGrid>

<h:inputText value="#{bean.texto}"> <f:ajax event="keyup"/>

</h:inputText>

<h:outputText id="texto" value="#{bean.texto}" />

</h:panelGrid> </h:form>

No trecho de código acima devemos tomar cuidado ao disparar uma solicitação Ajax com base no evento onkeyup. Observe que o nome real do evento é keyup. Este cuida de em disparar uma solicitação do Ajax. Em seguida, precisamos descobrir como fazer o processamento da visão parcial.

Renderizar a visão parcial

Em JSF 1.2 (e sem RichFaces) cada pedido retorna uma visão. Não necessitamos preocupar com que partes da visão JSF queremos atualizar. O conceito básico por trás de

Ajax é atualizar apenas as partes da página que realmente precisam. Para conseguir isso,

devemos informar esses componentes para o servidor cuja marcação iremos atualizar no navegador. O que tudo isto significa? Agora precisamos especificar quais componentes de visão queremos retornar. Uma visão parcial é processada pelo servidor. Uma parcela é atualizada e enviada como XML para o navegador onde o DOM é atualizado.

Este exemplo não é apenas um componente com o texto id. A tag tem um atributo de renderização que aponta para o ID do componente para renderizar a volta. Poderia também ser uma EL (Expression Language). Somando-se ao nosso exemplo, se pareceria com isso:

(7)

<h:inputText value="#{bean.texto}" > <f:ajax event="keyup" render="texto"/> </h:inputText>

<h:outputText id="texto" value="#{bean.texto}" />

Ao usar RichFaces, o mesmo atributo é chamado reRender. O evento que é especificado através do atributo deve ser um no qual o componente pai suporta. Ao visualizar o HTML gerado, teremos:

<input id="j_idt5:j_idt7" type="texto" name="j_idt5:j_idt7" onkeyup="mojarra.ab(this, event, 'keyup', 0, 'j_idt5:texto')" />

Processar a visão parcial

Ao especificar um evento que não está disponível no componente pai, uma mensagem de erro será exibida ao executar a página. Vejamos agora o código do bean:

@ManagedBean(name = "bean") public class Bean {

private String texto; // Métodos padrão GET e SET }

Vamos supor que também queremos mostrar e atualizar um contador com o comprimento do texto. Adicionar um nova propriedade no bean:

private Integer tamanho; // Métodos padrão GET e SET

Também adicionamos um método ouvinte Ajax para realizar a contagem, observe que o método recebe um objeto da classe AjaxBehaviorEvent:

public void tamanhoListener(AjaxBehaviorEvent event) { tamanho = texto.length();

}

Atualizar a página:

<h:inputText value="#{bean.texto}" >

<f:ajax event="keyup" render="texto tamanho" listener="#{bean.tamanhoListener}"/> </h:inputText>

<h:outputText id="texto" value="#{bean.texto}" />

<h:outputText id="tamanho" value="#{bean.tamanho}" />

Adicionamos um identificador para tamanho, use espaço como um separador. No exemplo acima, especificamos que o mesmo deve disparar uma solicitação Ajax e temos de especificar um evento. Se não for especificado, cada componente da interface do usuário tem um evento padrão na qual o pedido Ajax usaria para enviar. A tag <h:inputText>, o padrão evento Ajax é o evento onchange. Nosso exemplo, no entanto, funcionaria, só que ao em vez de onkeyup, teria que usar a tecla tab ou sair do campo de entrada para disparar a requisição Ajax.

(8)

Outro Exemplo

Agora que já estamos familiarizados como o Ajax funciona vejamos esse outro exemplo, comecemos pelo Bean:

import javax.faces.event.ActionEvent; import javax.faces.model.ManagedBean; import javax.faces.model.SessionScoped; @ManagedBean(name="calcula")

@SessionScoped

public class Calcula { private Integer conta = 0; public Integer getConta() { return conta++;

}

public void reset(ActionEvent ae) { conta = 0;

} }

Neste exemplo temos um contador para criarmos um simples aplicativo como um cronômetro. Um bean simples é utilizado para armazenar a contagem, bem como incrementá-la e redefini-la.

<!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"> <h:head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> <title>Ajax</title>

</h:head> <h:body>

<h:form id="form1" prependId="false">

<h:outputScript name="jsf.js" library="javax.faces" target="head"/>

<h:outputText id="cta" value="#{calcula.conta}"/> <br/>

<!-- Incrementar o contador no servidor e no cliente --> <h:commandButton id="btContar" value="Contar"

onclick="jsf.ajax.request(this, event, {execute: this.id, render: 'cta'}); return false;"/>

<br/>

<!-- Reiniciar o contador -->

<h:commandButton id="btReiniciar" value="Reiniciar"

onclick="jsf.ajax.request(this, event, {execute:'reset', render: 'cta'}); return false;"

actionListener="#{calcula.reset}"/> </h:form>

</h:body> </html>

(9)

Neste formulário temos três widgets: Um outputText e dois CommandButtons. O "cta" tem o conteúdo do valor da contagem. "btContar" adiciona um elemento ao contador a "cta" e reprocessa apenas o campo, ou seja, não há recarga completa da página. Da mesma forma, "btReiniciar" redefine o valor do contador para 0.

A tag <h:outputScript> informa que devemos incluir a biblioteca ajax em nossa página. Isto é necessário para a chamada para o response de jsf.ajax.request. O mesmo texto de saída "cta" é o alvo do ajax, não contém qualquer marcação fora do comum.

Temos "btContar" no qual o método onclick faz duas ações:Uma chamada jsf.ajax.request

• Retornar “false”. O retorno falso, para aqueles que não conhecem JavaScript, significa que não deve executar a submissão do formulário.

A chamada jsf.ajax.request, possui tem três parâmetros: 1. O objeto de chamada

2. O evento de chamada.

3. O último parâmetro é um objeto JavaScript com duas propriedades - uma executa a propriedade, que tem a lista de ids de todos os componentes JSF que vamos executar - já que estamos executando este botão, vamos incluí-lo na lista como 'this.id'. A segunda propriedade é todos os componentes JSF que queremos atualizar que neste caso, é apenas "cta”.

Por último, temos o botão “btReiniciar” com o evento onclick praticamente idêntico, mas não há um atributo adicional, "actionListener". Desde já estamos executando um 'reset', que significa que o JSF vai chamar esse método como parte do botão.

(10)

3. Navegação

O modelo de navegação JSF é tanto declarativa quanto programática, ou seja, a navegação pode ser configurada estaticamente em tempo de implantação ou dinamicamente durante o tempo de execução de uma aplicação Web.

Navegação de página para a aplicação JSF é tratado através de regras de navegação em um arquivo de configuração. A navegação pode especificar qual o componente que inicia a solicitação de Web, qual componente Web controla a resposta, e que valor faz com que a navegação para seguir o fluxo. Até agora, vimos uma navegação apenas com base no valor da sequência codificada de um atributo action. Também podemos controlar a navegação usando as expressões de ligação de valor e método de ligação de expressões. Navegação, em seguida, depende do valor da expressão.

Navegação estática e dinâmica

Ao controlar a navegação através de valores de String do atributo action, o caminho de navegação deve ser conhecido quando o aplicativo é implantado. Chamamos isso de

Navegação Estática, porque o fluxo é determinado estaticamente e não é modificado.

Sendo o mesmo para cada solicitação. Quando usamos a navegação estática, codificamos explicitamente um valor para o atributo ação de uma Custom tag JSF. Ao definir as regras de navegação em um arquivo de configuração. A regra especifica o fluxo de navegação quando o <from-outcome> de uma página coincide com o valor do atributo action. Quando isso ocorre, a navegação flui para o <to-view-id> especificado. Estes elementos são parte de um elemento de regra de navegação em um arquivo de configuração, o faces-config.xml.

Ao controlar a navegação através do valor de expressões de ligação ou métodos de ligação de expressões, o caminho de navegação não conhece quando o aplicativo é implantado. Na verdade, o fluxo de navegação pode variar de acordo com a solicitação pedida, dependendo do valor da expressão. Chamamos isso de Navegação Dinâmica.

Para uma navegação dinâmica, usamos uma expressão de valor de ligação ou o método de ligação de expressão, como o valor do atributo action. Com um valor de expressões de ligação, o valor da propriedade deve ser do tipo String. Com o método de expressões de ligação, o método não obtém parâmetro e retorna um valor do tipo String:

public String search();

O valor String retornado pelo método é comparado ao valor especificado na regra de navegação para determinar aonde o fluxo de controle deve ir.

Resumidamente:

Navegação Estática é recomendado quando a saída de uma página é conhecido

com antecedência e é sempre mais fácil prever a saída da página atual.

Navegação Dinâmica quando a saída da página atual é altamente imprevisível e a

(11)

Navegação Estática

Como mencionado anteriormente, se a resposta da página é conhecido antecipadamente, então este tipo de navegação pode ser escolhido. Tomemos um exemplo para ilustrar isso. Vamos exibir uma página da Web (a página de login) que solicita a entrada do usuário como o nome de usuário e a senha. Uma vez que esses valores são inseridos e o formulário é enviado, em seguida, uma página de boas-vindas é exibida. Aqui sabe-se que o resultado da página de login é sempre a página de boas vindas.

login.jsp

<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> <html> <head> <title>Aplicação de Login</title> </head> <body> <h1>Aplicação de Login</h1> <f:view> <h:form> <p>Login: <h:inputText value="#{LoginBean.username}" id="usernameTextField" required="true"/> <h:message for="usernameTextField" /> </p> <p>Senha: <h:inputSecret value="#{LoginBean.password}" id="passwordTextField" required="true"/> <h:message for="passwordTextField" /> </p>

<h:commandButton value="Submit Values" action="loginWelcome"/> </h:form>

</f:view> </body> </html>

Contém os campos de entrada do usuário para usuário e senha é mostrada a seguir. Um botão está ligado na extremidade da forma de apresentação da informação pedido para o servidor.

LoginBean.java

package net.javabeat.articles.jsf.navigation; public class LoginBean {

private String username; private String password; public LoginBean() { }

(12)

return username; }

public void setUsername(String username) { this.username = username;

}

public String getPassword() { return password;

}

public void setPassword(String password) { this.password = password;

} }

A classe UserBean encapsula o nome de usuário e senha para as propriedades que detém a informação solicitada. O nome do usuário e os valores da senha digitada pelo usuário será mapeada diretamente para UserBean.username e UserBean.password através de '#{UserBean.username}' as expressões e '#{UserBean.password}'.

faces-config.xml <?xml version='1.0' encoding='UTF-8'?> <faces-config version="1.2" 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-facesconfig_1_2.xsd"> <managed-bean> <managed-bean-name>LoginBean</managed-bean-name> <managed-bean-class> net.javabeat.articles.jsf.navigation.LoginBean </managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <description></description> <from-view-id>/login.jsp</from-view-id> <navigation-case> <from-outcome>loginWelcome</from-outcome> <to-view-id>/loginWelcome.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config>

Este arquivo de configuração contém uma entrada de definição do bean gerenciado por

LoginBean através do elemento "managed-bean”. Em seguida, vem a parte mais

importante que está relacionada ao Tratamento da navegação. Definimos a regra de navegação para a página login.jsp através dos elementos de regra de navegação

“from-view-id“. A presença de “from-view-id“ é que a regra será aplicável para o resultado da

página login.jsp. Em seguida, definimos um elemento interno chamado de navegação que define uma saída possivelmente o único para a página atual. Note a presença de elementos “from-outcome“ e “to-view-id“.

(13)

O valor “LoginWelcome” representa um dos resultados lógicos da página login.jsp. O valor para “to-view-id” aponta para a página de resposta seguinte a ser exibida. Para resumir, se a página atual é login.jsp e no resultado da página é "loginWelcome”, então a próxima página a ser exibida é a loginWelcome.jsp.

Navegação Dinâmica

Vejamos como controlar o comportamento de uma navegação dinâmica nesta seção. Vamos estender o exemplo acima para fazer isso. Neste momento, exibmos uma página de sucesso de login quando o nome de usuário e senha são valores combinados 'guest', mais uma página de falha de logon é exibida. Como os valores são inseridos pelo usuário apenas no tempo de execução, a próxima exibição a ser exibida não pode ser prevista. Isto significa que o ponto de vista seguinte a ser selecionado depende da execução de alguma regra de negócios no código.

Adicione o seguinte método na classe LoginBean: public String nextPage() {

if (username.equals("guest") && password.equals("guest")) { return "loginSuccess";

}

return "loginFailure"; }

O método nextPage() determina a próxima página a ser exibida com base nos valores do nome de usuário e a senha. Se tanto o nome de usuário e senha é 'guest' uma página de sucesso de login será exibida. Estamos retornando loginSucess (para o sucesso da entrada) e loginFailure (para falha na entrada).

Adicione o seguinte regra de navegação no arquivo faces-config.xml: <navigation-rule>

<description></description>

<from-view-id>/login.jsp</from-view-id> <navigation-case>

<from-outcome>loginSuccess</from-outcome> <to-view-id>/loginSuccess.jsp</to-view-id> </navigation-case>

<navigation-case>

<from-outcome>loginFailure</from-outcome> <to-view-id>/loginFailure.jsp</to-view-id> </navigation-case>

</navigation-rule>

Adicionamos dois elementos “navigation-case” para a página de login, uma para o sucesso e outra para o fracasso. O arquivo de configuração mostra a página login.jsp, se o resultado lógico for loginSuccess, em seguida, mostrar a página loginSuccess.jsp. Caso contrário, se o resultado lógico for loginFailure, depois a página loginFailure.jsp deve ser exibida. A página loginSuccess.jsp apenas exibe uma mensagem de Login Bem-Sucedido junto ao nome do usuário que é retirado do bean gerenciado por LoginBean.

(14)

loginSuccess.jsp

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

<head>

<title>Sucesso no Login</title> </head>

<body>

<h3>Entrada com Sucesso</h3> <f:view>

<h:form>

<p>Você teve sucesso com o Login.<p/>

<p>Bem vindo <h:outputText value="#{LoginBean.username}"/><p/> </h:form>

</f:view> </body> </html>

loginFailure.jsp

<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> <html> <head> <title>Login Falhou</title> </head> <body> <h3>Login Falhou</h3> <f:view> <h:form>

<p>O login id <h:outputText value="#{LoginBean.username}"/> não é encontrado.<p/>

<p>Por favor tente novamente...</p> </h:form>

</f:view> </body> </html>

Outros detalhes

Para finalizar, veremos os detalhes “left-over” do mecanismo de Navegação da JSF. Vamos cobrir o uso do elemento "request" bem como da especificação do uso wild-strings.

Normalmente, quando um redirecionamento é encontrado pelo servidor, a solicitação atual for encerrada, o controle é redirecionado para o navegador e este faz a requisição (que está disponível como a URL na instrução de redirecionamento). O mesmo acontece aqui também. Considere o seguinte elemento:

<navigation-case>

<from-outcome>loginFailure</from-outcome> <to-view-id>/loginFailure.jsp</to-view-id>

<redirect/>

(15)

Suponha-se, que o resultado da página login.jsp é loginFailure.jsp. Se o redirecionamento do elemento não está presente no arquivo de configuração, então a URL do navegador ainda mostra o login.jsp e não loginFailure.jsp (embora o conteúdo exibido no navegador será loginFailure.jsp). A presença do elemento redirecionará o controle do servidor para o navegador e é feita uma solicitação para a página de destino loginFailure.jsp.

Especificar wild-cards

Também é possível especificar um caractere wild-card (*) no elemento 'from-view-id'. Por exemplo, digamos que desejamos lidar com o mecanismo de navegação para todos os arquivos JSF dentro da pasta "registo", então podemos ter o seguinte elemento:

<navigation-rule> <from-view-id>/registro/*</from-view-id> <navigation-case> ... </navigation-case> </navigation-rule>

(16)

4. Facelets

Enquanto JavaServer Faces e JSP são feitos para serem alinhados, Facelets estão fora da especificação JSP e fornece uma alta performance, a JSF tecnologia é centrada no ponto de vista. Qualquer um que tenha criado uma página JSP será capaz de fazer o mesmo com

Facelets e utilizar a familiaridade de tags no padrão XML. A diferença está internamente,

onde toda a carga do fornecedor JSP é removida para aumentar consideravelmente a JSF como uma plataforma que pode proporcionar o simples desenvolvimento “plug-and-go“ sem a necessidade de desenvolvimento de tags JSP.

Aqui está um exemplo de como é fácil definir uma visão com Facelets: <html xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://java.sun.com/jsf/html" xmlns:c="http://java.sun.com/jstl/core"> <head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Hello</title>

</head> <body>

<form id="helloForm" jsfc="h:form">

<h2>Oi. Meu nome é Duke. Estou pensando em um número entre #{UserNumberBean.minimum} e #{UserNumberBean.maximum}. Pode advinhar qual é?

</h2>

<img id="waveImage" src="wave.med.gif" />

<input type="text" jsfc="h:inputText" id="userNo" value="#{UserNumberBean.userNumber}"

validator="#{UserNumberBean.validate}"/>

<input type="submit" jsfc="h:commandButton" id="submit" action="success" value="Submeter" />

<p />

<h:message showSummary="true" id="errors1" for="userNo"/> <p />

<c:forEach begin="1" end="4" varStatus="v"> #{view.viewId} #{v.index}<br/>

</c:forEach> </form>

</body> </html>

Você pode estar pensando que a marcação parece extremamente familiar. Esse é o ponto. Não existe qualquer necessidade de aprender uma outra linguagem de templates ou esquema.

Por que usar Facelets?

Facelets não é dependente de um contêiner JSP. Isso significa que podemos começar a

usar os novos recursos de JSF. Aqui está uma pequena lista dos recursos do Facelets: • Trabalha com JSF 1.1 e JSF 1.2, incluindo a RI da Sun e o Apache MyFaces.

(17)

Tempo zero para o desenvolvimento de tags para UIComponentsRápido templating/decoradores para componentes e PáginasCapacidade de especificar UIComponents em arquivos separados • Line – Tag – Atribute, erros são reportados precisamente

Especificar as tags em arquivos separados, mesmo embalado com jar • Suporte a EL completo, incluindo funções

• Em tempo de compilação Validação EL

• Arquivos de configuração XML não são necessárias, mas estão disponíveis

Todos os desenvolvedores desejam um projeto mais amigável. Desenvolvedores passam um tempo considerável definindo: UIComponents, Conversores e Validadores no arquivo

faces-config.xml. Facelets só exige a especificação de um apelido ao nome para ligar seus

objetos em suas páginas (sem XML necessário). A chave é a facilidade de integração e desenvolvimento.

JSF 2 Templating com exemplo Facelets

Neste exemplo, mostramos a utilização de 4 tags Facelets para construir a página a partir de um modelo:

ui:insert – Usado em arquivo de modelo, define o conteúdo que vai substituir pelo

arquivo que carrega o modelo. O conteúdo pode ser substituir por um tag ui:define.ui:define – Define o conteúdo que é inserido no modelo com uma correspondência

pela tag ui:insert.

ui:include – Semelhante a tag jsp:include do JSP padrão, inclui o conteúdo de outra

página XHTML.

ui:composition – Se for usado com um atributo "template", o modelo especifico é

carregado, e os filhos desta tag definem o layout do modelo, caso contrário, é um grupo de elementos, que pode ser inserido em algum lugar. Além disso, JSF remove as tags outside da tag ui:composition.

1. Layout do modelo

Para JSF, um arquivo modelo é apenas um simples arquivo XHTML, com poucas tags no padrão Facelets para definir o layout do modelo.

commonLayout.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"

(18)

xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head>

<h:outputStylesheet name="common-style.css" library="css" /> </h:head> <h:body> <div id="page"> <div id="header"> <ui:insert name="header"> <ui:include src="/template/common/commonHeader.xhtml" /> </ui:insert> </div> <div id="content"> <ui:insert name="content" > <ui:include src="/template/common/commonContent.xhtml" /> </ui:insert> </div> <div id="footer"> <ui:insert name="footer" > <ui:include src="/template/common/commonFooter.xhtml" /> </ui:insert> </div> </div> </h:body> </html>

Neste modelo, definimos o layout da Web padrão, com os seguintes detalhes:

Usamos a tag h:outputStylesheet para incluir um arquivo CSS no cabeçalho para denominar o layout de página inteira.

Usamos a tag ui:insert para definir três seções substituíveis: cabeçalho, conteúdo e rodapé.

Usamos a tag ui:include para fornecer um conteúdo padrão, se nenhuma substituição é especificada quando o modelo for usado.

2. Cabeçalho, Conteúdo e Rodapé

Codificação para os três conteúdos da página.

commonHeader.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"> <body>

<ui:composition>

<h1>Este é o cabeçalho padrão</h1> </ui:composition>

</body> </html>

(19)

<?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"> <body>

<ui:composition>

<h1>Este é o conteúdo padrão</h1> </ui:composition>

</body> </html>

commonFooter.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"> <body>

<ui:composition>

<h1>Este é o rodapé padrão</h1> </ui:composition>

</body> </html>

Quando estas páginas forem inseridas no arquivo modelo, todas as tags ui:composition serão removidas. Por exemplo:

commonHeader.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"> <body>

TODAS AS TAGS acima desta linha serão removidas pelo JSF <ui:composition>

<h1>Este é o cabeçalho padrão</h1> </ui:composition>

TODAS AS TAGS abaixo desta linha serão removidas pelo JSF </body>

</html>

JSF utiliza os seguintes elementos para inserir no arquivo de modelo: <ui:composition>

<h1>Este é um cabeçalho padrão</h1> </ui:composition>

Ao inserir o modelo commonLayout, tornou-se:

commonLayout.xhtml

... <h:body>

(20)

<div id="page"> <div id="header">

<h1>Este é um cabeçalho padrão</h1> </div>

...

3. Utilizando template

Para fazer uso de um modelo já existente, por exemplo. CommonLayout.xhtml, utilize a tag

ui:composition com um atributo template. Vejamos os seguintes exemplos: default.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:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:body> <ui:composition template="template/common/commonLayout.xhtml"> </ui:composition> </h:body> </html>

A página JSF carrega o modelo commonLayout.xhtml e exibe todo o conteúdo da página padrão.

page1.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"

(21)

xmlns:ui="http://java.sun.com/jsf/facelets"> <h:body>

<ui:composition template="/template/common/commonLayout.xhtml"> <ui:define name="content">

<h2>Este é o conteúdo da Página 1</h2> </ui:define>

<ui:define name="footer">

<h2>Este é o rodapé da Página 1</h2> </ui:define>

</ui:composition> </h:body>

</html>

Ao carregar a página JSF para o modelo commonLayout.xhtml e usar a tag ui:define para substituir a tag ui:insert, que foi definida no arquivo modelo.

Enquanto o nome da tag ui:define é comparado com o nome da tag ui:insert, que foi definida para o modelo, ui:insert teve seu conteúdo substituído.

(22)

5. Richfaces

RichFaces, como a maioria dos outros frameworks de componentes projetados para uso com JSF, foi extensivamente modificado para permitir total compatibilidade. Nesta seção descreveremos todas as ações necessárias e configurações que devem ser feitas para conectar os componentes RichFaces em uma aplicação JSF.

Baixar os RichFaces

A última versão dos componentes RichFaces está disponível na área de Downloads do JBoss RichFaces na comunidade JBoss:

http://labs.jboss.com/jbossrichfaces/downloads

São arquivos binários (baixar os arquivos *.bin.zip ou *.bin.tar.gz) contém compilado, pronto para usar a versão do RichFaces com o conjunto básico. Para começar com RichFaces no sistema de arquivo de computador criar uma nova pasta com o nome "RichFaces", e nesta baixe e descompacte o arquivo com os binários.

Adicionar as bibliotecas RichFaces para o projeto

Na pasta com os arquivos descompactados anteriormente abra pasta lib. Esta pasta contém três arquivos *.jar com a API, interface do usuário e as bibliotecas de execução. Copiar os arquivos JARs na pasta lib para a pasta WEB-INF/lib da aplicação JSF.

Uma aplicação JSF com RichFaces assume que os arquivos JARs a seguir estão disponíveis no projeto: beanutils-1.7.0.jar, collections-3.2.jar, commons-digester-1.8.jar, commons-logging-1.0.4.jar, jhighlight-1.0.jar.

Registrar o RichFaces no web.xml

Depois de adicionar as bibliotecas RichFaces ao projeto é necessário registrá-las no arquivo

web.xml. Adicionar seguintes linhas neste arquivo:

...

<!-- Ligar o "Blue Sky" skin para o projeto --> <context-param>

<param-name>org.richfaces.SKIN</param-name> <param-value>blueSky</param-value>

</context-param>

<!-- Fazer o RichFaces se espalhar para os controles padrão HTML --> <context-param>

<param-name>org.richfaces.CONTROL_SKINNING</param-name> <param-value>enable</param-value>

</context-param>

<!-- Definir e mapear o filtro RichFaces --> <filter>

(23)

<display-name>RichFaces Filter</display-name> <filter-name>richfaces</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>richfaces</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> ...

Finalmente, o arquivo web.xml deve ficar assim: <?xml version="1.0"?> <web-app version="2.5" 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_2_5.xsd"> <display-name>Greeter</display-name> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>server</param-value> </context-param> <context-param> <param-name>org.richfaces.SKIN</param-name> <param-value>blueSky</param-value> </context-param> <context-param> <param-name>org.richfaces.CONTROL_SKINNING</param-name> <param-value>enable</param-value> </context-param> <filter> <display-name>RichFaces Filter</display-name> <filter-name>richfaces</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>richfaces</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <listener> <listener-class>com.sun.faces.config.ConfigureListener</listener-class> </listener> <!-- Faces Servlet --> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>

(24)

<!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <login-config> <auth-method>BASIC</auth-method> </login-config> </web-app>

managed bean

A aplicação "RichFaces Greeter" necessita de um managed bean. Na pasta do projeto criar um novo managed bean com nome de Usuario no pacote demo com o seguinte código: package demo;

public class Usuario { private String nome = ""; public String getNome() { return nome;

}

public void setNome(String nome) { this.nome = nome;

} }

Registrando o managed bean no arquivo faces-cofig.xml: <?xml version="1.0" encoding="UTF-8"?> <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xi="http://www.w3.org/2001/XInclude" 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-facesconfig_1_2.xsd"> <managed-bean> <description>Bean do Usuario</description> <managed-bean-name>usuario</managed-bean-name> <managed-bean-class>demo.Usuario</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>nome</property-name> <property-class>java.lang.String</property-class> <value/> </managed-property> </managed-bean> </faces-config>

O aplicativo "RichFaces Greeter" tem apenas uma página JSP. Criar a página index.jsp na pasta raiz do conteúdo Web e adicionar o seguinte código:

(25)

<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <!-- RichFaces tag library declaration -->

<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%> <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%> <html> <head> <title>RichFaces Greeter</title> </head> <body> <f:view> <a4j:form>

<rich:panel header="RichFaces Greeter" style="width: 315px"> <h:outputText value="Seu nome:"/>

<h:inputText value="#{usuario.nome}">

<f:validateLength minimum="1" maximum="30"/> </h:inputText>

<a4j:commandButton value="Obter Saudação" reRender="greeting"/> <h:panelGroup id="greeting">

<h:outputText value="Olá, " rendered="#{not empty usuario.nome}"/> <h:outputText value="#{usuario.nome}"/>

<h:outputText value="!" rendered="#{not empty usuario.nome}"/> </h:panelGroup> </rich:panel> </a4j:form> </f:view> </body> </html>

A aplicação utiliza três componentes RichFaces: rich:panel utilizado como um contêiner visual para a informação; a4j:commandButton com suporte embutido para Ajax que permite prestar uma saudação dinâmica após um respose e a4j:form auxilia ao botão executar a ação.

Observamos, que a biblioteca RichFaces deve ser declarado em cada página JSP. Para

Facelets devemos adicionar as seguintes linhas para declaração da biblioteca de tag:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich"> ... </ui:composition>

Demonstração dos Componentes

RichFaces possui diversos componentes e tem mais de 20 atributos específicos, além de

atributos gerais que podem ser substituídos. No entanto, no uso comum dos componentes não são difíceis de configurar, como a maioria dos atributos com padrões razoáveis. Vejamos alguns desses componentes a seguir.

(26)

Calendar: Um componente pop-up que permite seleções de data.

Pick List: Uma seleção e ordenação componente. Lista de Escolha que pode mover os itens

entre as áreas disponíveis e selecionadas, para cima e para baixo na área selecionada.

AutoComplete: Substituto para o componente de entrada Suggestion Box que fornece

sugestões clicáveis para preencher ou completar uma entrada.

Tab Panel: um componente de saída que cria páginas com guias.

(27)
(28)

6. Primefaces

PrimeFaces é um projeto de extensão que tem o objetivo ser uma biblioteca de

componentes JSF leve e rápida, sendo um conjunto de diversos componentes. Este é um projeto estendido pois define componentes úteis que falta em outras bibliotecas da JSF. Utiliza padrões e é altamente compatível com o framework JSF.

A extensão PrimeFaces não é somente um conjunto de componentes, conversores e comportamentos para o cliente. Também consiste de plugins úteis para o framework Maven e vários add-ons simplificadores para a Web e, especialmente, para o desenvolvimento JSF. A extensão PrimeFaces é um projeto open source que está sob a licença do Apache. Pode-se usá-lo livremente em projetos de código aberto ou comerciais Pode-segundo os termos da licença.

Características do PrimeFaces

Resumidamente PrimeFaces é uma biblioteca de componentes de código aberto para a JSF com mais de 100 componentes. Possui as seguintes características:

• Um variado conjunto de componentes de interface para o usuário (DataTable, AutoComplete, HtmlEditor, Charts, entre outros);

• Somente a configuração XML é necessária e não há dependências necessárias; • Built-in Ajax baseado no padrão JSF 2.0 Ajax APIs;

• Mais de 25 temas internos; e

• Documentação com exemplos de código.

Aplicativo Exemplo

Vamos construir uma aplicação exemplo utilizando a extensão PrimeFaces com as seguintes características:

1. Uma tela de Login que recebe o nome e a senha do usuário para autenticá-lo.

2. Ao ser bem-sucedido o login será exibida uma tela de pesquisa do usuário. Os usuários podem pesquisar outros usuários pelo seu nome. Os resultados da pesquisa serão exibidos em um DataTable com paginação, classificação e filtragem de apoio. 3. Ao clicar em uma linha, os detalhes do usuário serão exibidos em um formulário. Inicialmente, realizar o download da bibliotecas do JSF:

http://javaserverfaces.java.net/download.html

Copiar os arquivos: jsf-api-X.X.X.jar, jsf-impl-X.X.X.jar e jstl-X.X.X.jar para a pasta: WEB-INF/lib

(29)

http://www.primefaces.org/downloads.html Colocar o arquivo primefaces X.X.X.jar na pasta: WEB-INF/lib

Configurar FacesServlet no arquivo web.xml: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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_2_5.xsd" > <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> </web-app>

Criar um arquivo chamado faces-config.xml na pasta WEB-INF: <?xml version="1.0" encoding="utf-8"?> <faces-config 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-facesconfig_2_0.xsd" version="2.0">

Não há declarações ManagedBean aqui pois usamos anotações @ManagedBean. -->

</faces-config>

Criar a página index.jsp, que desvia para a tela de login: <jsp:forward page="login.jsf"></jsp:forward>

Criar a página login.xhtml:

<html xmlns="http://www.w3c.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"

xmlns:p="http://primefaces.prime.com.tr/ui"> <h:head>

<link type="text/css" rel="stylesheet" href="themes/bluesky/skin.css" /> </h:head>

<h:body> <center>

<p:panel header="Entrada no Sistema" style="width: 350;"> <h:form>

(30)

<h:panelGrid columns="2" cellpadding="2">

<h:outputLabel for="#{userManagedBean.username}" value="Usuário"/> <h:inputText value="#{userManagedBean.username}" label="UserName"> </h:inputText>

<h:outputLabel for="#{userManagedBean.password}" value="Senha"/> <h:inputSecret value="#{userManagedBean.password}"></h:inputSecret> <h:commandButton type="submit" value="Login"

action="#{userManagedBean.login}"> </h:commandButton> </h:panelGrid> </h:form> </p:panel> <div><h:messages ></h:messages></div> </center> </h:body> </html>

Obter e disponibilizar o tema blusky de pacote PrimeFaces. Criar um arquivo chamado

home.xhtml que contém o UserSearchForm, Resultados do dataTable e UserDetails Panel.

<html xmlns="http://www.w3c.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"

xmlns:p="http://primefaces.prime.com.tr/ui"> <h:head>

<link type="text/css" rel="stylesheet" href="themes/bluesky/skin.css" /> </h:head>

<h:body> <center> <h:form>

<p:panel header="Formulário de Busca para Usuários" style="width: 700;"> <h:form>

<h:panelGrid columns="3" cellpadding="2">

<h:outputLabel for="#{userManagedBean.searchUser}" value="Usuário"/> <h:inputText value="#{userManagedBean.searchUser}" label="Usuário"> </h:inputText>

<h:commandButton type="submit" value="Search" action="#{userManagedBean.searchUser}">

</h:commandButton> </h:panelGrid> </h:form>

</p:panel>

<p:dataTable var="user" value="#{userManagedBean.searchUsersResults}" selection="#{userManagedBean.selectedUser}" selectionMode="single" dynamic="true" onRowSelectUpdate="userUpdateForm" onRowUnselectUpdate="userUpdateForm" rowSelectListener="#{userManagedBean.onUserSelect}" rowUnselectListener="#{userManagedBean.onUserUnselect}" paginator="true" rows="5" style="width: 700">

<p:column sortBy="#{user.userId}" filterBy="#{user.userId}"> <f:facet name="header">

<h:outputText value="Id" /> </f:facet>

(31)

<h:outputText value="#{user.userId}" /> </p:column>

<p:column sortBy="#{user.username}" filterBy="#{user.username}"> <f:facet name="header">

<h:outputText value="Nome" /> </f:facet>

<h:outputText value="#{user.username}" /> </p:column>

<p:column sortBy="#{user.emailId}" filterBy="#{user.emailId}"> <f:facet name="header">

<h:outputText value="Email" /> </f:facet>

<h:outputText value="#{user.emailId}" /> </p:column>

<p:column parser="date" sortBy="#{user.dob}" filterBy="#{user.dob}"> <f:facet name="header"> <h:outputText value="DOB" /> </f:facet> <h:outputText value="#{user.dob}" > <f:convertDateTime pattern="dd/MM/yyyy" /> </h:outputText> </p:column> </p:dataTable>

<p:panel id="userDetailsPanelId" header="Detalhes" style="width: 700;"> <h:panelGrid columns="2" cellpadding="2" id="userUpdateForm" border="0" > <h:outputLabel for="#{userManagedBean.selectedUser.userId}" value="ID"/> <h:inputText value="#{userManagedBean.selectedUser.userId}" style="width: 100;" readonly="true"></h:inputText> <h:outputLabel for="#{userManagedBean.selectedUser.username}" value="Usuário"/> <h:inputText value="#{userManagedBean.selectedUser.username}" readonly="true"> </h:inputText>

<h:outputLabel for="#{userManagedBean.selectedUser.emailId}" value="Email"/> <h:inputText value="#{userManagedBean.selectedUser.emailId}" readonly="true"> </h:inputText>

<h:outputLabel for="#{userManagedBean.selectedUser.gender}" value="Sexo"/> <h:inputText value="#{userManagedBean.selectedUser.gender}"

readonly="true"> </h:inputText>

<h:outputLabel for="#{userManagedBean.selectedUser.dob}" value="DOB"/> <h:inputText value="#{userManagedBean.selectedUser.dob}" readonly="true"> <f:convertDateTime pattern="dd/MM/yyyy" /> </h:inputText> </h:panelGrid> </p:panel> </h:form> </center> </h:body> </html>

Criar a classe de domínio User.java: package x25.com.tutorial;

(32)

import java.util.Date; public class User { private Integer userId; private String username; private String emailId; private String phone; private Date dob; private String gender; private String address;

public User() { }

public User(Integer userId, String username, String emailId, String phone, Date dob, String gender, String address) {

this.userId = userId; this.username = username; this.emailId = emailId; this.phone = phone; this.dob = dob; this.gender = gender; this.address = address; }

// Métodos padrões GET/SET }

Criar a classe UserService.java, que atua como uma simulação da tabela na base de dados. package x25.com.tutorial; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; public class UserService {

private static final Map<Integer, User> USERS_TABLE = new HashMap<Integer, User>();

static {

USERS_TABLE.put(1, new User(1, "Administrator", "admin@gmail.com", "9000510456", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(2, new User(2, "Guest", "guest@gmail.com", "9247469543", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(3, new User(3, "John", "John@gmail.com", "9000510456", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(4, new User(4, "Paul", "Paul@gmail.com", "9247469543", new Date(), "M", "Hyderabad"));

(33)

USERS_TABLE.put(5, new User(5, "raju", "raju@gmail.com", "9000510456", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(6, new User(6, "raghav", "raghav@gmail.com", "9247469543", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(7, new User(7, "caren", "caren@gmail.com", "9000510456", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(8, new User(8, "Mike", "Mike@gmail.com", "9247469543", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(9, new User(9, "Steve", "Steve@gmail.com", "9000510456", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(10, new User(10, "Polhman", "Polhman@gmail.com", "9247469543", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(11, new User(11, "Roger", "Rogermoor@gmail.com", "9000510456", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(12, new User(12, "Robin", "Robinhood@gmail.com", "9247469543", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(13, new User(13, "Sean", "Sean@gmail.com", "9000510456", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(14, new User(14, "Gabriel", "Gabriel@gmail.com", "9247469543", new Date(), "M", "Hyderabad"));

USERS_TABLE.put(15, new User(15, "raman", "raman@gmail.com", "9000510456", new Date(), "M", "Hyderabad"));

}

public Integer create(User user) { if(user == null) {

throw new RuntimeException("Não foi possível criar Usuário. Objeto é nulo"); }

Integer userId = this.getMaxUserId(); user.setUserId(userId);

USERS_TABLE.put(userId, user); return userId;

}

public void delete(User user) { if(user == null) {

throw new RuntimeException(

"Não foi possível excluir o Usuário. Objeto é nulo"); }

USERS_TABLE.remove(user.getUserId()); }

public Collection<User> getAllUsers() { return USERS_TABLE.values();

}

public User getUser(Integer userId) { return USERS_TABLE.get(userId); }

public Collection<User> searchUsers(String username) {

String searchCriteria = (username == null)?"":username.toLowerCase().trim(); Collection<User> users = USERS_TABLE.values();

Collection<User> searchResults = new ArrayList<User>(); for (User user : users) {

if (user.getUsername() != null &&

user.getUsername().toLowerCase().trim().startsWith(searchCriteria)) { searchResults.add(user);

(34)

} }

return searchResults; }

public void update(User user) {

if(user == null || !USERS_TABLE.containsKey(user.getUserId())) { throw new RuntimeException(

"Não é possível alterar o usuário. Objeto é nulo ou ID [" + user.getUserId() + "] é inválido." );

}

USERS_TABLE.put(user.getUserId(), user); }

protected Integer getMaxUserId() {

Set<Integer> keys = USERS_TABLE.keySet(); Integer maxId = 1;

for (Integer key : keys) { if(key > maxId) { maxId = key; } } return maxId; } }

Criar a classe UserManagedBean.java: package x25.com.tutorial; import java.util.Collection; import javax.faces.application.FacesMessage; import javax.faces.bean.ApplicationScoped; import javax.faces.bean.ManagedBean; import javax.faces.context.FacesContext; import org.primefaces.event.SelectEvent; import org.primefaces.event.UnselectEvent; @ManagedBean @ApplicationScoped

public class UserManagedBean {

UserService userService = new UserService(); private String username;

private String password; private String searchUser;

private Collection<User> searchUsersResults; private User selectedUser;

public String getUsername() { return username;

}

public void setUsername(String username) { this.username = username;

}

public String getPassword() { return password;

(35)

}

public void setPassword(String password) { this.password = password;

}

public User getSelectedUser() { if (selectedUser == null){ selectedUser = new User(); }

return selectedUser; }

public void setSelectedUser(User selectedUser) { this.selectedUser = selectedUser;

}

public Collection<User> getSearchUsersResults() { return searchUsersResults;

}

public void setSearchUsersResults(Collection<User> searchUsersResults) { this.searchUsersResults = searchUsersResults;

}

public String getSearchUser() { return searchUser;

}

public void setSearchUser(String searchUser) { this.searchUser = searchUser;

}

public String login() {

if ("test".equalsIgnoreCase(getUsername()) && "test".equals(getPassword())) { return "home";

} eles {

FacesContext context = FacesContext.getCurrentInstance();

context.addMessage("username", new FacesMessage("Usuário ou senha Inválido")); return "login";

} }

public String searchUser() {

String username = (this.searchUser == null)? "":this.searchUser.trim(); this.searchUsersResults = userService.searchUsers(username);

System.out.println(searchUsersResults); return "home";

}

public String updateUser() {

userService.update(this.selectedUser); return "home";

}

public void onUserSelect(SelectEvent event) { }

public void onUserUnselect(UnselectEvent event) { }

}

Isso é tudo o que precisamos fazer. Execute o aplicativo e veja toda a funcionalidade deste aplicativo junto ao tema blusky.

(36)

7. Validação e Conversão

JavaServer Faces suporta um mecanismo para validar os dados de componentes editáveis.

Cada componente em JSF cria mensagens de erro durante o ciclo de vida e pode-se atribui-los ao objeto FacesContext. Assim, cada mensagem está ligada a um componente na árvore de componentes e a mensagem é exibida no modo de exibição no final do Ciclo de

Vida da JSF conforme a seguinte figura:

Obviamente que diferentes cenários poderiam impactar de forma diferente as descrições do Ciclo de Vida. Devemos observar que os processos de conversão e validação ocorrem nas fases de Aplicar os Valores de Solicitação, Validações do Processo e Retornar a Resposta. Devemos esclarecer uma questão mais básica: o que é conversão? Simplificando, é o processo que garante se o objeto é ou não do tipo certo. Aqui estão duas conversões típicas:

Valor de um tipo String é convertido para um java.util.Date.Valor de um tipo String é convertido para um Float.

Quanto à validação, garante que os dados contém o conteúdo esperado. Aqui estão duas validações típicas:

(37)

java.util.Date é MM/aaaa.

Float está entre 1.0F e 100.0F.

Fases do Ciclo de Vida

O principal objetivo da conversão e validação é assegurar que os valores foram devidamente limpos antes de atualizar os dados do modelo. Posteriormente, quando chega a hora de invocar os métodos da aplicação para realmente realizar algo com esses dados, pode-se seguramente fazer certas suposições sobre o estado do seu modelo. Conversão e

validação permite se concentrar na Regra de Negócio ao invés das qualificações tediosas

de dados de entrada, tais como dados nulos, qualificadores de tamanho ou limites de alcance, etc

Faz sentido, então, que os processos de conversão e validação acontecerem antes dos dados de componente vinculados ao seu modelo do BackBean no modelo de atualização de dados fase do Ciclo de Vida. A conversão ocorre na fase de aplicar valores de solicitação e validação na fase de validação do processo.

Sobre o atributo imediato

Notamos que os processos de conversão e validação representa o fluxo de aplicação quando o atributo imediato o componente UIInput é definido como false. Foram o atributo definido para a conversão, verdadeira e validação iria ocorrer no início do ciclo de vida, durante a fase de valores aplica-se a requisição (ver a próxima figura). Existem casos em que é útil como o gerenciamento de listas dinâmicas e até mesmo ignorando a validação por completo (quando utilizado com um componente UICommand).

A próxima figura mostra onde a Conversão e Validação ocorre no Ciclo de Vida da aplicação JSF foram o atributo imediato definido como verdadeiro.

Referências

Documentos relacionados

6) O Conselho Tutelar articulará ações para o estrito cumprimento de suas atribuições, de modo a agilizar o atendimento, promoção, proteção, prevenção e defesa, junto aos

III – Realizar abertura de créditos suplementares provenientes de excesso de arrecadação, quando o saldo positivo das diferenças, acumuladas mês a mês, entre a arrecadação

Características Estrutura Corpo Docente Experiência Insper Incrição online na página do curso no site do

³ Carga horária superior a carga horária máxima de 32 horas, que pode ser destinada ao ensino, por isso tem-se a necessidade de se dividir a disciplina entre 3 professores, a menos

As informações necessárias sobre plantas tóxicas precisam de maior difusão para especialistas na área de saúde como também para a população em geral, evitando assim

O(s) analista(s) de investimento declara(m) que as opiniões contidas neste relatório refletem exclusivamente suas opiniões pessoais sobre a companhia e seus valores mobiliários e

Ao nível de protecção social os dados disponibilizados pela segurança social não espelham a realidade da nova freguesia porque se referem ao antigo território contudo,

A Cooperativa aplicou os seguintes pronunciamentos, já aprovados pelo CMN: CPC 00 (R2)-Estrutura Conceitual para Elaboração e Apresentação das Demonstrações Contábeis -