JavaServer Faces (JSF)
Parte II
Sistemas de Informação
Prof. Vinicius Cardoso Garcia
[email protected]
Licença do Material
Este Trabalho foi licenciado com uma
Licença
CreaHve Commons -‐
Atribuição-‐NãoComercial-‐
ComparHlhaIgual 3.0 Não Adaptada
.
Mais informações visite
Referências
• Notas de aula baseadas no material do curso:
– Programação Web, Módulo 6, versão 1.0 – Novembro/2007
– JEDI: Java Educa>on & Development Ini>a>ve (DFJUG-‐ BRASIL)
• HALL, Marty. Core Servlets and Java Server Pages, Pren>ce Hall, 2000
• GOODWILL, James. Mastering Jakarta Struts, Wiley, 2002 • Paul Deitel e Harvey Deitel. Java -‐ Como Programar -‐ 8ª
Edição. Pren>ce Hall -‐ Br, 2010. • Curso de JSF do Wesley Bez
– h:p://www.wesleybez.com.br/ensino/moodle/course/ view.php?id=6
LogísHca
• Apresentação do professor
• Material
• Dúvidas? Interrompam a
vontade...
• Celulares silenciosos
• Exercício
ObjeHvos
•
Ao final desta aula, o estudante será capaz de:
–
Conhecer a classe FacesContext
–
Entender os componentes validadores e
para conversão de >po
–
Criar componentes e como desenvolver um
conjunto de tags personalizadas
O Que veremos?
• FacesContext e a Árvore de Componentes • FacesContext e o ExternalContext
• Validadores • Conversores
FacesContext e a Árvore de
Componentes
•
Para cada view que u>lize os elementos
UI:
– Existe uma estrutura de árvore de
componentes responsável por sua
modelagem
•
A especificação do JSF requer que todas
suas implementações:
– Armazenem essa árvore de componentes
dentro do objeto FacesContext
Árvore de Componentes
•
Permite o acesso a todos os componentes
da interface com o usuário e seus dados
•
Adicionar componentes a view através de
programação
•
Alterar ou adicionar conversores ou
validadores dinamicamente
•
Remover componentes
•
U>lizada para prover redirecionamento de
tela dentro do framework faces
Árvore de Componentes
• O redirecionamento pode ser feito modificando a árvore de componentes atual que é acessada pelo usuário, pela árvore de componentes situada em outra página
...
String targetPage = "/newPage.jsp";
FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getViewHandler().createView(context, targetPage);
FacesContext e o ExternalContext
•
Objeto ExternalContext, acessado através do
FacesContext, permite acessar o ambiente onde
o framework está sendo executado
•
Para uma aplicação WEB, permite acessar:
– O objeto H:pServletRequest representando a requisição atual
– O mapa dos objetos armazenados na sessão do usuário
– O objeto ServletContext que representa o contexto de toda a aplicação WEB
FacesContext e o ExternalContext
• Para recuperar o objeto de H:pServletRequest:
FacesContext context =
FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
FacesContext e o ExternalContext
• Infelizmente, não existe nenhum modo para acessar diretamente o objeto H:pSession associado à sessão. Entretanto, os objetos armazenados
dentro desta podem ser acessados por um objeto do >po Map, do seguinte modo:
Map sessionMap =
context.getExternalContext().getSessionMap();
• Para recuperar o ServletContext representado na aplicação, pode-‐se usar a seguinte instrução:
ServletContext servletContext = (ServletContext) context.getExternalContext().getContext();
Uma vez que temos acesso a estes objetos, podemos então fazer uso de outras técnicas de programação WEB.
Validadores Padrão do JSF
• JSF provê um conjunto de validadores que podemos u>lizar na nossa aplicação
• Três validadores padrões:
– DoubleRangeValidator
• Tag JSP: validateDoubleRange • Atributos: minimum, maximum
– LengthValidator
• Tag JSP: validateLength
• Atributos: minimum, maximum
– LongRangeValidator
• Tag JSP: validateLongRange
UHlizando os Validadores
Padrão
• Fazer uso dos validadores padrões, basta inserir a tag de JSP
do validador dentro do corpo do componente de entrada
...
<h:outputLabel for="password">
<h:outputText value="Password : "/> </h:outputLabel>
<h:inputSecret id="password" value="#{loginPage.password}"> <f:validateLength minimum="4"/> </h:inputSecret> <br/> <h:commandButton action="#{loginPage.performLogin}" value="Login"/> </h:form> ...
UHlizando os Validadores
Padrão
• Fazer uso dos validadores padrões, basta inserir a tag de JSP
do validador dentro do corpo do componente de entrada
...
<h:outputLabel for="password">
<h:outputText value="Password : "/> </h:outputLabel>
<h:inputSecret id="password" value="#{loginPage.password}"> <f:validateLength minimum="4"/> </h:inputSecret> <br/> <h:commandButton action="#{loginPage.performLogin}" value="Login"/> </h:form> ...
Este é o código JSP para a página de login que implementamos na lição anterior usando JSF. Será
modificado de tal forma que o campo senha aceita somente uma entrada com o tamanho mínimo de 4 caracteres.
UHlizando os Validadores
Padrão
• Fazer uso dos validadores padrões, basta inserir a tag de JSP
do validador dentro do corpo do componente de entrada
...
<h:outputLabel for="password">
<h:outputText value="Password : "/> </h:outputLabel>
<h:inputSecret id="password" value="#{loginPage.password}"> <f:validateLength minimum="4"/> </h:inputSecret> <br/> <h:commandButton action="#{loginPage.performLogin}" value="Login"/> </h:form> ...
A tag que define o campo de senha <h:inputSecret> foi modificada de modo que a tag não é mais fechada
propriamente na mesma linha que era declarada. Agora faz uso de uma outra tag </h:inputSecret>
UHlizando os Validadores
Padrão
• Fazer uso dos validadores padrões, basta inserir a tag de JSP
do validador dentro do corpo do componente de entrada
...
<h:outputLabel for="password">
<h:outputText value="Password : "/> </h:outputLabel>
<h:inputSecret id="password" value="#{loginPage.password}"> <f:validateLength minimum="4"/> </h:inputSecret> <br/> <h:commandButton action="#{loginPage.performLogin}" value="Login"/> </h:form> ...
Para que a tag que define a validação funcionar <f:validateLength>, foi inserida
entre a abertura e fechamento da tag <h:inputSecret>.
UHlizando os Validadores
Padrão
• Para aceitar uma entrada que restrinja pelo tamanho máximo
em vez de um tamanho mínimo, devemos subs>tuir o
atributo minimum pelo atributo maximum, e especificar este tamanho.
• Podemos também fazer uso de dois atributos
simultaneamente, definindo um intervalo no qual uma entrada seja aceita.
• Este trabalho será́ o mesmo feito com as tags
<f:validateLongRange> e <f:validateDoubleRange>, a única diferença serão os >pos de dados aceitos.
Validação Personalizada
•
Estender a classe do componente UI que
recebe a requisição Podemos sobrescrever
seu método de validação
–
Solução não-‐portável
•
Criar um método de validação externo
•
Criar nossas próprias implementações da
interface Validator em separado
•
Registrá-‐las no framework e então colocá-‐
las no componente UI
Método de Validação Externo
• Criar um método de validação externo é idên>co a criar um método de aplicação para manipulação eventos:
– Criar um método que esteja dentro de um certo conjunto de regras e dentro de um JavaBean gerenciado pelo framework – Fazer a ligação deste método com o componente UI
apropriado
• O método deve estar conforme as seguintes regras:
– Ser declarado public, com o retorno >po void
– Não exis>r limitações quanto ao nome do método
– Receber os seguintes parâmetros, na seguinte ordem: FacesContext ctxt, UIInput component, Object value – Deve declarar o lançamento de uma exceção do >po
Método de Validação Externo
•
Cabeçalho de um método de validação
personalizado:
public void validatePassword(FacesContext ctxt, UIInput component, Object value)
throws ValidatorException
– O objeto da classe FacesContext nos provê acesso a fontes externas
– O objeto da classe UIInput é a instância do
componente de entrada que requer validação
– Object possui o valor dentro do componente que requer a validação
Implementando o Método de
Validação Externo
•
O objeto FacesContext fornece um acesso aos
recursos externos, como os objetos de request
e escopo da sessão, como também a outros
objetos dentro do framework JSF
•
O componente visual UIInput é a instância do
componente de entrada que requer a validação
– tendo uma instância deste objeto, obtemos oacesso ao estado do componente.
•
Finalmente, o Object é o valor deste objeto
Implementando o Método de
Validação Externo
•
O processo de validação é simples.
•
Caso o framework não receba qualquer
ValidatorExcep>ons, a entrada é aceita.
•
Caso o framework receba um
ValidatorExcep>on o processo é
interrompido e a página contendo o
componente de entrada é novamente
reapresentada.
Implementando o Método de
Validação Externo
public void validatePassword(FacesContext ctxt, UIInput component, Object value)
throws ValidatorException { if (null == value)
return;
if (!(isPasswordValid(value.toString()))) {
FacesMessage message = new FacesMessage("Input error", "Password is not valid");
throw new ValidatorException(message); }
}
protected boolean isPasswordValid(String password) { ...
Implementando o Método de
Validação Externo
public void validatePassword(FacesContext ctxt, UIInput component, Object value)
throws ValidatorException { if (null == value)
return;
if (!(isPasswordValid(value.toString()))) {
FacesMessage message = new FacesMessage("Input error", "Password is not valid");
throw new ValidatorException(message); }
}
protected boolean isPasswordValid(String password) { ...
A classe FacesMessage modela uma mensagem dentro da JSF. O primeiro parâmetro em seu construtor é um itulo, enquanto que o segundo são os detalhes da mensagem. Isto
é uHlizado para indicar a JSF que a mensagem será reconhecida como uma mensagem de erro.
Implementando o Método de
Validação Externo
• Para ser realmente capaz de exibir uma mensagem de erro gerada,
devemos adicionar uma tag <h:messages> ou <h:message> na página JSP
...
<h:outputLabel for="password">
<h:outputText value="Password : "/> </h:outputLabel>
<h:inputSecret id="password" value="#{loginPage.password}"> <f:validateLength minimum="4"/>
</h:inputSecret>
<h:message for="password" styleClass="error"/>
<br/>
<h:commandButton action="#{loginPage.performLogin}" value="Login"/> </h:form>
Externo vs. Em separado
•
Diferença:
–
Como eles são u>lizados?
–
Um método do validator externo é mais
u>lizado para validação de código específico
de um componente em par>cular
–
Uma implementação do validator em
separado é u>lizada para códigos de
validação de propósito geral que serão
reu>lizados extensivamente dentro das
aplicações
Registrando um componente
validador
• Para usar um componente validador personalizado, devemos
primeiro registrá-‐lo para ser reconhecido pela JSF.
• Isto é realizado colocando uma entrada de configuração no
arquivo faces-‐ config.xml.
<validator>
<description>
A validator for checking the password field </description> <validator-id>AlternatingValidator</validator-id> <validator-class> jedi.sample.jsf.validator.AlternatingValidator </validator-class> </validator>
Registrando um componente
validador
• Para usar um componente validador personalizado, devemos
primeiro registrá-‐lo para ser reconhecido pela JSF.
• Isto é realizado colocando uma entrada de configuração no
arquivo faces-‐ config.xml.
<validator>
<description>
A validator for checking the password field </description>
<validator-id>AlternatingValidator</validator-id> <validator-class>
jedi.sample.jsf.validator.AlternatingValidator </validator-class>
Para configurar a entrada para um novo validador basta definir um idenHficador pelo
qual será referenciado na JSF e o nome da classe deve ser totalmente qualificado para implementar a funcionalidade da validação
Usando um componente
validador
• Para usar o componente validador registrado, usamos a tag <f:validator> e fornecemos o atributo validatorId como iden>ficação do validador
...
<h:outputLabel for="password">
<h:outputText value="Password : "/> </h:outputLabel>
<h:inputSecret id="password" value="#{loginPage.password}">
<f:validator validatorId="AlternatingValidator"/>
</h:inputSecret>
<h:message for="password" styleClass="error"/> <br/>
<h:commandButton action="#{loginPage.performLogin}" value="Login"/> </h:form>
Adicionando atributos para o
validador
• Se observarmos o validador padrão validateLength fornecido pela JSF, podemos ver que este contém dois atributos pela qual a operação poderá́ ser
modificada futuramente.
• De modo semelhante, podemos ter atributos para o validador de modo personalizado.
– Adicionamos uma propriedade dentro de nossa classe
Um valor que pode ser fornecido para este atributo e fazer uso da tag <f:a:ribute>:
...
<h:outputLabel for="password">
<h:outputText value="Password : "/> </h:outputLabel>
<h:inputSecret id="password" value="#{loginPage.password}"> <f:validator validatorId=”AlternatingValidator”/>
<f:attribute name=”interval” value=”5”/> </h:inputSecret>
<h:message for=”password” styleClass=”error”/> <br/>
<h:commandButton action="#{loginPage.performLogin}" value="Login"/> </h:form>
Conversores
•
Converte os valores informados pelo
usuário no formato ou >po apropriado
u>lizado internamente pelo servidor
•
Bi-‐direcional
: Podem ser u>lizados para
alterar os dados internos que são
mostrados para o usuário
•
Definem os métodos getAsString() e
getAsObject() que podem ser chamados
pelo framework no momento apropriado
DateTimeConverter
•
U>lizado para converter entradas do
usuário em instâncias de java.u>l.Date
•
Provê um número de atributos com os
quais o desenvolvedor pode especificar o
formato u>lizado na conversão
–
Formato especificado é forçado quando o
usuário preenche sua entrada
–
Se violado, um erro de conversão ocorrerá e
o framework não con>nuará o
processamento
DateTimeConverter
• Estes são os atributos disponíveis:
– dateStyle – um dos es>los de data definidos pelo
java.text.DateFormat. Os valores possíveis são: default, short, long, medium ou full.
– parseLocale – a localidade a ser usada como referência durante a
conversão.
– HmeStyle – um dos es>los de data definido pelo java.text.DateFormat.
Os valores possíveis são: default, short, medium, long ou full.
– HmeZone – a >me zone u>lizada.
– type – uma String que define quando a saída será́ uma data, uma
instância do >po >me, ou ambos. Os valores possíveis, são: date, >me e both. O valor padrão é date.
– panern – o padrão de formatação a ser usado na conversão. Se um
valor para esse atributo for definido, o sistema irá ignorar qualquer valor para dateStyle, >meStyle e type.
NumberConverter
•
U>lizado para converter entradas de
número e forçar formatações especiais
nelas
•
Quaisquer padrões ou símbolos
indicados nos atributos são forçados
como regras para o usuário
•
Se violadas, um erro de conversão
ocorrerá e o processamento será́
terminado
NumberConverter
• Os seguintes atributos são usados para podermos controlar o comportamento desse
componente de conversão
– currencyCode – código monetário >po ISO 4217 a ser u>lizado ao formatar.
– currencySymbol – o símbolo monetário a ser usado ao formatar.
– groupingUsed – indica se o valor u>lizará separadores de grupo (por exemplo, ponto depois de cada 3 dígitos).
– integerOnly – indica que apenas a parte inteira de um número deve ser mostrada. Isso significa que a parte decimal será́ truncada antes do dado ser armazenado em uma propriedade escondida
(bound).
– locale – a localidade usada para referência de formação.
– maxIntegerDigits – o número máximo de dígitos mostrados ou usados na parte inteira do número.
– maxFracHonDigits – o número máximo de dígitos mostrados ou usados na parte decimal do número.
– minFracHonDigits – o número mínimo de dígitos mostrados ou usados na parte decimal do número.
– minIntegerDigits – o número mínimo de dígitos mostrados ou usados na parte inteira do número.
– panern – o padrão a ser u>lizado quando formatamos ou mostramos o número. Para mais detalhes sobre os padrões permi>dos, verifique no JavaDoc por java.text.NumberFormat.
– type – indica quando o número a ser conver>do deve ser tratado como moeda, percentual ou número. Para mais detalhes, verifique no JavaDoc por java.text.NumberFormat.
Conversores Personalizados
• Podem ser criados através da criação de uma classe que implemente a interface Converter
• Esta interface define dois métodos:
public Object getAsObject(FacesContext ctxt, UIComponent component, String input)
public Object getAsString(FacesContext ctxt, UIComponent component, Object source)
Método getAsObject
•
Esse método é chamado pelo framework
para o componente de conversão associado
quando precisa converter os dados de
entrada do usuário de sua representação
textual em outro >po de objeto.
•
O conceito na implementação desse
método é simples: atua na operação de
processamento do argumento String
fornecido e retorna um Object que irá
representá-‐lo no servidor.
Método getAsString
• Esse método faz conversões bidirecionais.
• Ele dita a representação em String do dado interno relevante. O conceito por trás da implementação desse objeto é mais simples do que a do método getAsObject
• Ela mostra o valor armazenado no objeto >po
Double como um número com símbolos de grupos • Essa implementação é mais simples porque sabemos
com clareza o formato exato do nosso dado de entrada.