Java EE 6: Começando com Bean Validation

Java EE 6: Começando com Bean Validation
lucasas
lucasas

Compartilhe

Não existe tarefa mais comum hoje em dia do que validar dados em uma aplicação. Por exemplo, validamos se na camada de apresentação o usuário preencheu algum campo obrigatório, depois fazemos a mesma lógica de validação em nossa regra de negócio e por último validamos se os dados que serão salvos no banco também estão corretos. O que na maioria das vezes os desenvolvedores fazem é validar estas regras em todos os lugares, e muitas vezes resulta em validações complicadas e possíveis erros na aplicação. Muitos desenvolvedores consideram essa tarefa enfadonha.

Na nova versão do Java EE lançada dezembro de 2009 existem grandes novidades: Servlets 3.0, JAX-RS, CDI, JSF 2.0 e a Bean Validation, definida pela JSR 303. Com a Bean Validation é possível realizarmos validações atráves de metadados (anotações) e as utilizarmos em todas as camadas de nossa aplicação.

Podemos até mesmo criar nossas próprias regras de validações e aplicarmos em outros pontos do nosso sistema. Essas regras podem ser facilmente integradas com JPA e JSF, por exemplo. Vamos considerar uma classe que represente um contato:

Banner da promoção da black friday, com os dizeres: A Black Friday Alura está chegando. Faça parte da Lista VIP, receba o maior desconto do ano em primeira mão e garanta bônus exclusivos. Quero ser VIP
 public class Contato {

private String nome;

private String email;

// getters e setters

public void enviaEmail() { // codigo envio de email } } 

E vamos adicionar nossas regras de validação utilizando a Bean Validation:

 public class Contato {

@NotEmpty @Pattern(regexp = ".+@.+\\\\.```a-z
+") private String email; @NotEmpty private String nome;

// getters e setters

public void enviaEmail() { // codigo envio de email } } 

A anotação @NotEmpty garante que o email não poderá ser vazio assim como o atributo nome. No atributo email também colocamos a anotação @Pattern, onde podemos passar qualquer expressão regular, que o Bean Validation validará o valor passado ao atributo nome com a expressão regular.

Lembrando que o Bean Validation é uma especificação e como toda especificação, para utilizarmos precisamos de uma implementação para a utilizarmos. A implementação usada nos exemplos é a Hibernate Validator, e é a implementação de referência.

Integrando com o JSF

O código abaixo mostra um formulário simples utilizando JSF, que chama um método enviaEmail do ManagedBean quando clicamos no botão "EnviaEmail":

 <h:form id="formulario"> <h:panelGrid columns="3"> <h:inputText id="email" value="#{contato.email}"/> <h:message for="email" styleClass="error"/> <h:commandButton action="#{contato.enviaEmail}" value="Enviar Email"/> </h:panelGrid> </h:form> 

Precisamos ainda anotar nossa classe Contato com @ManagedBean(name="contato") e @RequestScoped para que a mesma seja um ManageBean e consiga integrar-se com o JSF. Quando clicarmos no botão "Enviar Email" automaticamente será validado se o atributo email foi preenchido a atende a expressão regular da anotação @Pattern.

Podemos muitas vezes nos deparar com algum caso onde é necessário fazermos uma validação um pouco mais específica, algo que não esteja implementado por padrão no Bean Validation. Validar um CEP seria um bom exemplo. O primeiro passo para fazermos nossa própria validação é criar uma anotação que sugira o nome desta validação.

 @Constraint(validatedBy = CepValidator.class) @Documented @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Cep { String message() default "Cep inválido"; Class<?>\[\] groups() default { }; Class<? extends Payload>\[\] payload() default { };

} 

Reparem que em nenhum momento fizemos de fato a validação se o CEP é válido ou não. Por isso anotamos a anotação CEP que acabamos de criar com @Constraint e setamos o atributo validatedBy com a classe que está nossa validação realmente. O próximo passo é criarmos a classe CEPValidator que fará a validação. Esta classe tem que obrigatóriamente implementar a interface javax.validation.ConstraintValidator:

 public class CepValidator implements ConstraintValidator<Cep, String> {

private Pattern pattern = Pattern.compile("```0-9
{5}-```0-9
{3}");

@Override public void initialize(Cep constraintAnnotation) {

}

@Override public boolean isValid(String value, ConstraintValidatorContext context) { Matcher m = pattern.matcher(value); return m.matches(); }

} 

No método isValid verificamos e retornamos um booleano dizendo se a String passada como argumento está de acordo com a expressão regular que criamos no topo da classe. Podemos agora validar qualquer atributo de algum Java Bean, devendo apenas anotar o atributo com a nossa recém criada @CEP. Por exemplo:

 public class Contato {

@Cep private String cep;

// getters e setters } 

Para rodar esse exemplo precisamos de um servidor de aplicação compatível com o Java EE 6, como o Glassfish 3.0. A premissa do Bean Validation é que muitos outros frameworks acabem por adotar um único mecanismo de validação, sendo possível reaproveitar o código criado aqui. O Caelum Stella, que fornece diversos validadores para sistemas que envolvem o domínio brasileiro, em breve será compatível com essa especificação, possibilitando que você utilize-o em todas as diversas especificações que compões o Java EE.

Além disso precisamos de um Servidor de Aplicação compatível com a versão 6 do Java EE. Por enquanto o único servidor que implementa essa versão é o Glassfish v3.0 que por sinal também é uma implementação de referência.

Veja outros artigos sobre Programação