Java e OO

Validação com Bean Validation

Bean Validation é uma especificação que permite validar objetos com facilidade em diferentes camadas da aplicação. A vantagem de usar Bean Validation é que as restrições ficam inseridas nas classes de modelo.

Precisamos de uma implementação de Bean Validation. As implementações podem adicionar restrições customizadas, além das fornecidas pela especificação. Usaremos Hibernate Validator, a implementação de referência.

Para desenvolver nosso exemplo, criaremos um projeto Maven e incluiremos o código abaixo no pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.algaworks.blog</groupId>
  <artifactId>validacao-beanvalidation</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.0.1.Final</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-library</artifactId>
      <version>1.3</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>de.odysseus.juel</groupId>
      <artifactId>juel</artifactId>
      <version>2.1.3</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.0</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

As restrições de Bean Validation são em forma de anotações, disponíveis no pacote javax.validation.constraints. Veja um exemplo:

package com.algaworks.blog.model;

import javax.validation.constraints.*;

public class Cliente {

  @NotNull
  @Size(min = 3, max = 20)
  private String nome;

  @NotNull
  @Size(min = 3, max = 40)
  private String sobrenome;

  // getters e setters

}

A anotação @NotNull valida se o valor da propriedade não é nulo e @Size valida se a string tem a quantidade de caracteres entre o mínimo e máximo informados. Existem diversas outras anotações e você também pode criar as suas próprias.

Para verificar o funcionamento, criaremos uma classe de teste com JUnit no source folder src/test/java, chamada ClienteTest.

package com.algaworks.blog.model;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

// outros imports

public class ClienteTest {

  private Validator validator;

  @Before
  public void setUp() {
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    this.validator = factory.getValidator();
  }

  @Test
  public void naoDeveAceitarSobrenomeCurto() {
    Cliente cliente = new Cliente();
    cliente.setNome("Ana");
    cliente.setSobrenome("S.");

    Set<ConstraintViolation<Cliente>> restricoes = validator.validate(cliente);

    assertThat(restricoes, hasSize(1));
    assertThat(getNomePrimeiraPropriedade(restricoes), is("sobrenome"));
  }

  private String getNomePrimeiraPropriedade(
      Set<ConstraintViolation<Cliente>> restricoes) {
    return restricoes.iterator().next().getPropertyPath().iterator().next().getName();
  }

  @Test
  public void naoDeveAceitarClienteSemNomeESobrenome() {
    Cliente cliente = new Cliente();

    Set<ConstraintViolation<Cliente>> restricoes = validator.validate(cliente);

    assertThat(restricoes, Matchers.hasSize(2));
  }

  @Test
  public void devePassarNaValidacaoComNomeESobrenomeInformados() {
    Cliente cliente = new Cliente();
    cliente.setNome("Ana");
    cliente.setSobrenome("Silva");

    Set<ConstraintViolation<Cliente>> restricoes = validator.validate(cliente);

    assertThat(restricoes, empty());
  }

}

Todos os nossos testes devem passar.

JavaServer Faces integra com Bean Validation para validar objetos preenchidos pelas páginas que criamos.

Para testar, incluiremos uma implementação do JSF no pom.xml da nossa aplicação.

<dependency>
  <groupId>org.glassfish</groupId>
  <artifactId>javax.faces</artifactId>
  <version>2.2.2</version>
  <scope>compile</scope>
</dependency>

Depois, criaremos um managed bean chamado CadastroClienteBean.

package com.algaworks.blog.controller;

// imports

@ManagedBean(name = "cadastro")
public class CadastroClienteBean {

  private Cliente cliente = new Cliente();

  public void cadastrar() {
    System.out.println("Nome: " + this.cliente.getNome());
    System.out.println("Sobrenome: " + this.cliente.getSobrenome());
  }

  public Cliente getCliente() {
    return cliente;
  }

}

Agora, criaremos uma página chamada CadastroCliente.xhtml, na pasta src/main/webapp.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
  <meta charset="UTF-8" />
</h:head>
<h:body>
  <h:form>
    <h:messages/>

    <h:panelGrid columns="2">
      <h:outputLabel value="Nome" />
      <h:inputText value="#{cadastro.cliente.nome}" />

      <h:outputLabel value="Sobrenome" />
      <h:inputText value="#{cadastro.cliente.sobrenome}" />

      <h:outputLabel/>
      <h:commandButton value="Cadastrar" 
        action="#{cadastro.cadastrar}" />
    </h:panelGrid>
  </h:form>
</h:body>
</html>

Pronto! Podemos implantar nossa aplicação no Apache Tomcat (ou outro container) e acessar a página pelo endereço http://localhost:8080/validacao-beanvalidation/faces/CadastroCliente.xhtml. A validação funcionará automaticamente.

Para aprender mais sobre Bean Validation, JSF e diversas outras tecnologias, conheça os cursos online da AlgaWorks, que são completos e substituem a necessidade de cursos presenciais.

Acesse ou baixe o código-fonte completo deste artigo no GitHub.

Fundador da AlgaWorks, uma das principais escolas de desenvolvimento Java e front-end do Brasil. Autor de diversos livros e cursos de Java e front-end. Palestrante no JavaOne San Francisco em 2016, a maior conferência de Java do mundo. Programador desde os 14 anos de idade (1995), quando desenvolveu o primeiro jogo de truco online e multiplayer (que ficou bem famoso na época).

Olá,

o que você achou deste conteúdo? Conte nos comentários.

Junte-se a mais de 100.000 pessoas

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

Você se Inscreveu com Sucesso!