Java EE 6: Começando com Bean Validation

Alura
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 promocional da Imersão Cloud DevOps da Alura e Google Cloud com o texto "INSCRIÇÕES ABERTAS PARA A PRIMEIRA EDIÇÃO DA IMERSÃO CLOUD DEVOPS" e a informação de 3 aulas gratuitas com certificado. A imagem mostra um desenvolvedor focado usando fones de ouvido em um computador, com uma colega trabalhando ao fundo, e um botão chamativo com a frase "GARANTA A SUA VAGA".
 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