• Nenhum resultado encontrado

JSF 2 Templating com exemplo Facelets

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:

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.

Um exemplo de trabalho

Daqui em diante vamos utilizar uma aplicação exemplo para demonstrar os conceitos discutidos. A aplicação demonstra as capacidades de conversão e validação. Tenhamos em mente que a aplicação é muito simples e não necessariamente exaustiva: Nosso objetivo não é construir um aplicativo para uso no mundo real, depois de tudo.

• Uso do padrão JSF conversores para converter dados de campo de formulário; • Uso de componentes JSF padrão para validar dados de campo de formulário; • Escrever conversores e validadores personalizados;

Registrar conversores e validadores personalizados no arquivo faces-config.xml; • Personalizar mensagens de erro padrão.

O aplicativo de exemplo é um simples formulário de registro do usuário. Nosso objetivo é reunir os dados do usuário como nome, idade, endereço de correio eletrônico e número de telefone. Então, vamos mostrar como utilizar a conversão e validação para garantir que os dados coletados são apropriados e corretos.

A aplicação utiliza três páginas JSP:

index.jsp que redireciona o usuário para UserRegistration.jsp

UserRegistration.jsp que contém os campos da aplicação de formulários

Results.jsp que notifica o aplicativo no qual o usuário foi registrado

Começaremos início com um olhar para as opções de codificação de processos de conversão do JSF.

Conversão

Como mencionado anteriormente, a conversão é o processo que assegura ao objeto. Podemos utilizar conversores prontos ou personalizados. JSF fornece muitos conversores padrões. Também podemos ligar nosso próprio conversor personalizado, implementar a interface e converter. A seguinte tabela mostra os identificadores do conversor e as classes de implementação correspondentes utilizados pela JSF para uma conversão de dados simples. A maioria das conversões de dados acontece automaticamente.

javax.faces.BigDecimal javax.faces.convert.BigDecimalConverter javax.faces.BigInteger javax.faces.convert.BigIntegerConverter javax.faces.Boolean javax.faces.convert.BooleanConverter javax.faces.Byte javax.faces.convert.ByteConverter javax.faces.Character javax.faces.convert.CharacterConverter javax.faces.DateTime javax.faces.convert.DateTimeConverter javax.faces.Double javax.faces.convert.DoubleConverter

javax.faces.Float javax.faces.convert.FloatConverter

Um conversor para cada ocasião

O código abaixo demonstra uma conversão padrão no campo idade do usuário. A tag JSF está configurado como tal:

<h:inputText id="age" value="#{UserRegistration.user.age}"/>

UserRegistration.user.age representa uma propriedade de valor de ligação que é do tipo

inteiro. Para as ligações de ambos os tipos primitivos, BigInteger ou BigDecimal, JSF escolhe um conversor de padrão. No entanto, também podemos usar um conversor específico para granularidade maior usando a tag <f:converter/>, conforme a codificação a seguir:

<h:inputText id="age" value="#{UserRegistration.user.age}"> <f:converter id="javax.faces.Short"/>

</h:inputText>

Embora JSF trata primitivas e como muito bem por padrão, quando se lida com dados de data devemos especificar a tag <f:convertDateTime/>. Esta marca é baseada no pacote

java.text e utiliza curto, longo, e os padrões personalizados. Aqui está um exemplo:

<h:inputText id="birthDate" value="#{UserRegistration.user.birthDate}"> <f:convertDateTime pattern="MM/yyyy"/>

</h:inputText>

Este exemplo demonstra como usar a tag <f:convertDateTime/> para garantir que a data de nascimento do usuário é conversível em um objeto de data no formatado como “MM/AAAA” (mês/ano).

Além de converter formatos de data e hora, JSF fornece um conversor especial para lidar com números como porcentagens ou moeda. Este conversor lida com o agrupamento (como vírgula), número de dígitos decimais, símbolos de moeda, entre outros. Por exemplo, o uso de <f:convertNumber/> seguinte é uma técnica para lidar com moeda:

<h:inputText id="salary" value="#{UserRegistration.user.salary}"> <f:convertNumber maxFractionDigits="2" groupingUsed="true"

currencySymbol="$" maxIntegerDigits="7" type="currency"/> </h:inputText>

Conversores Personalizados

Conversão de dados personalizado é necessário se você precisa converter os dados de campo em um objeto de valor específico do aplicativo, como nos exemplos a seguir:

String para o objeto Telefone (Telefone.ddd, Telefone.numero)String para o objeto Nome (Nome.principal, Nome.apelido)String para o objeto Produto (Produto.numero, Produto.revisao) Para criar um conversor personalizado, você deve fazer o seguinte:

Implementar o método getAsObject, que converte um campo (String) em um objeto (por exemplo, Telefone).

Implementar o método getAsString, que converte um objeto (por exemplo Telefone) em uma String.

• Cadastrar seu conversor personalizado no contexto Faces. • Insirir o conversor em sua JSP com a tag <f:converter/>.

Veja por si mesmo como essas etapas se encaixam no ciclo de aplicação JSF. JSF chama o método getAsObject do conversor personalizado durante a fase de aplicar valores pedido. Este é o lugar onde o conversor deve converter o valor String da requisição para o tipo de objeto desejado, e então retornar o objeto para o armazenamento no componente JSF correspondente.

Quando o valor for processado de volta para o ponto de vista, JSF chama o método

getAsString na fase da renderização da resposta. Isto significa que o conversor é também

responsável pela transformação dos dados de objetos de volta para uma representação de sequência.

Passo 1: Implementar a interface Converter.

import javax.faces.convert.Converter;

import org.apache.commons.lang.StringUtils; ...

public class TelefoneConverter implements Converter { ...

}

Passo 2: Implementar o método getAsObject que converte uma String para um objeto da

classe Telefone.

public class TelefoneConverter implements Converter { ...

public Object getAsObject(

FacesContext context, UIComponent component, String valor) { if (StringUtils.isEmpty(valor)) {

return null; }

Telefone fone = new Telefone();

String [] foneComps = StringUtils.split(value," ,()-"); String codPais = foneComps[0];

fone.setCodPais(codPais); if ("1".equals(codPais)) { String ddd = foneComps[1]; String prefixo = foneComps[2]; String numero = foneComps[3]; fone.setDDD(ddd);

fone.setPrefixo(prefixo); fone.setNumero(numero); } else {

phone.setNumero(valor); }

return fone; }

}

Passo 3: Implementar o método getAsString que converte a classe Telefone para uma

String.

public class TelefoneConverter implements Converter { ...

public String getAsString(FacesContext context, UIComponent component, Object value) {

return value.toString(); }

}

public class Telefone implements Serializable { ...

public String toString(){ if (countryCode.equals("1")){

return codPais + " " + ddd + " " + prefixo + " " + numero; } eles {

return numero; }

} }

Passo 4: Registrar o conversor personalizado com o contexto. Isso pode ser executado em

uma das seguintes maneiras. A primeira opção é registrar a classe TelefoneConverter com o ID de (por exemplo) x25.TelefoneConverter. Este ID será então utilizado pela tag

<f:converter/> em suas páginas JSP.

<converter>

<converter-id>arcmind.TelefoneConverter</converter-id>

<converter-class>x25.com.tutorial.TelefoneConverter</converter-class> </converter>

Alternativamente, pode-se registrar a classe TelefoneConverter para lidar com todos os objetos Telefone automaticamente, como mostrado a seguir.

<converter>

<converter-for-class>x25.com.tutorial.Telefone</converter-for-class>

<converter-class>x25.com.tutorial.TelefoneConverter</converter-class> </converter>

Passo 5: Usa o conversor em seus JSPs. A execução do seguinte passo depende da opção

de qual registo foi escolhido. Ao optar por registrar a classe TelefoneConverter com o ID de x25.TelefoneConverter, então utiliza-se a tag <f:converter/> como mostrado abaixo.

<f:converter converterId="x25.TelefoneConverter" /> </h:inputText>

Se optar por registrar a classe TelefoneConverter para lidar com todos os objetos Telefone automaticamente, então não será necessário usar a tag <f:converter/> em seus JSPs. Aqui está o código para o Passo 5, sem a tag conversor.

<h:inputText id="phone" value="#{RegistroUsuario.usuario.telefone}"> [ Veja só sem conversor !]

</h:inputText>

Validação

Existe quatro formas de validação dentro JSF: • Componentes Built-in de validação • Validação em nível de aplicativo

Componentes personalizados de validação (que implemente a interface Validator) • Métodos de validação através de BackBeans

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

Vejamos um estudo de caso do Ciclo de Vida para o campo nome do nosso formulário de cadastro. As referências de código são destinas a ser interpretadas como um pseudocódigo.

Aqui está uma lista dos componentes de validação padrão fornecidos pelo JSF:

DoubleRangeValidator: valor local de componentes deve ser do tipo numérico, e

estar em um intervalo especificado pelos valores mínimos e/ou máximo.

LongRangeValidator: valor local de componentes deve ser do tipo numérico e

conversível para o tipo long; deve estar no intervalo especificado pelos valores mínimos e/ou máximo.

LengthValidator: Tipo deve ser String; o tamanho deve estar no intervalo

especificado pelos valores mínimos e/ou máximo.

Padrão de Validação

Em nosso aplicativo exemplo a idade do usuário pode ser de qualquer tipo inteiro válido (byte, short, int). Porque não faz sentido permitir que uma idade de, digamos, -2, vamos adicionar uma validação para o campo. Este é um código de validação simples para garantir a integridade do modelo de dados para o campo idade:

<h:inputText id="idade" value="#{RegistroUsuario.usuario.idade}"> <f:validateLongRange maximum="150" minimum="0"/>

</h:inputText>

Podemos especificar restrições quanto ao comprimento do campo nome. Podemos realizar isso da seguinte forma:

<h:inputText id="nome" value="#{RegistroUsuario.usuario.nome}"> <f:validateLength minimum="2" maximum="25" />

</h:inputText>

A estratégia de Conversão e Validação permite que facilmente e rapidamente começar (conversores padrão, validação, validação in-line) durante a fase de prototipação, e migrar para soluções de produção mais sofisticadas (objetos personalizados, mensagens personalizadas) durante as fases de desenvolvimento posterior.

Ao longo de tudo isso, ciclo de vida da aplicação JSF fornece uma infraestrutura confiável para garantir a integridade do modelo de dados.

Documentos relacionados