DEV Community

Cover image for Quando usar Jakarta Validation
Uiratan Cavalcante
Uiratan Cavalcante

Posted on

Quando usar Jakarta Validation

As anotações de validação do Jakarta Validation (Bean Validation) (@NotBlank, @Size, @Email, etc.) fazem mais sentido quando queremos validar dados fora da entidade, ou seja, antes mesmo de criar um objeto de domínio. Isso geralmente acontece em camadas externas da aplicação, como:

  • Entrada de dados via API (DTOs no Controller)
  • Formulários em aplicações web
  • Importação de dados de fontes externas

📌 Quando usar as anotações de validação?

1️⃣ Validação de entrada em APIs (DTOs no Controller) ✅

Essa é a melhor prática para evitar que dados inválidos cheguem à camada de domínio.

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

public class AutorRequest {
    @NotBlank(message = "O nome é obrigatório")
    private String nome;

    @NotBlank(message = "O email é obrigatório")
    @Email(message = "Formato de email inválido")
    private String email;

    @NotBlank(message = "A descrição é obrigatória")
    @Size(max = 400, message = "A descrição não pode passar de 400 caracteres")
    private String descricao;

    public Autor toModel() {
        return new Autor(nome, email, descricao); // Criação segura, pois os dados já foram validados
    }
}
Enter fullscreen mode Exit fullscreen mode

E no Controller, usamos @Valid para garantir que os dados recebidos estejam corretos:

import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/autores")
public class AutorController {

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public void cadastrarAutor(@RequestBody @Valid AutorRequest autorRequest) {
        Autor autor = autorRequest.toModel();
        System.out.println("Autor cadastrado: " + autor.getNome());
    }
}
Enter fullscreen mode Exit fullscreen mode

Vantagem: A validação ocorre antes de criar o objeto Autor, evitando que ele seja construído em estado inconsistente.


2️⃣ Validação de formulários em aplicações web ✅

Se estivermos lidando com uma aplicação web (exemplo: Spring MVC com Thymeleaf), podemos validar os dados de um formulário automaticamente.

@Controller
@RequestMapping("/autores")
public class AutorController {

    @PostMapping
    public String cadastrarAutor(@ModelAttribute @Valid AutorRequest autorRequest, BindingResult result) {
        if (result.hasErrors()) {
            return "formulario"; // Retorna o formulário com erros
        }

        Autor autor = autorRequest.toModel();
        System.out.println("Autor cadastrado: " + autor.getNome());
        return "redirect:/sucesso";
    }
}
Enter fullscreen mode Exit fullscreen mode

Aqui, o BindingResult armazena os erros e pode ser usado para exibir mensagens ao usuário.


3️⃣ Validação automática em métodos de serviços com @Validated

Se quisermos validar parâmetros de um método de serviço, podemos usar @Validated diretamente:

import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import jakarta.validation.constraints.NotBlank;

@Service
@Validated
public class AutorService {

    public void criarAutor(@NotBlank String nome) {
        System.out.println("Criando autor: " + nome);
    }
}
Enter fullscreen mode Exit fullscreen mode

Se nome for nulo ou vazio, uma ConstraintViolationException será lançada automaticamente.


🚀 Quando NÃO faz sentido usar as anotações de validação?

🔴 Dentro do construtor de uma entidade de domínio → Porque o Jakarta Validation não impede diretamente a criação de um objeto inválido.

🔴 Se você precisar de validação imediata e rápida → Aqui faz mais sentido usar Assert do Spring (org.springframework.util.Assert).

Exemplo usando Assert no construtor da entidade:

import org.springframework.util.Assert;
import java.time.Instant;

public class Autor {

    private final String nome;
    private final String email;
    private final String descricao;
    private final Instant instanteCriacao;

    public Autor(String nome, String email, String descricao) {
        Assert.hasText(nome, "O nome é obrigatório");
        Assert.hasText(email, "O email é obrigatório");
        Assert.hasText(descricao, "A descrição é obrigatória");
        Assert.isTrue(descricao.length() <= 400, "A descrição não pode passar de 400 caracteres");

        this.nome = nome;
        this.email = email;
        this.descricao = descricao;
        this.instanteCriacao = Instant.now();
    }
}
Enter fullscreen mode Exit fullscreen mode

Aqui o erro ocorre imediatamente se o nome, e-mail ou descrição forem inválidos.


🎯 Conclusão

Situação Melhor abordagem
Evitar dados inválidos antes da criação do objeto Jakarta Validation (@NotBlank, @Valid) no DTO
Evitar objetos inconsistentes no momento da criação Spring Assert no construtor
Validar dados recebidos via API DTO + @Valid no Controller
Validar parâmetros de métodos em services @Validated no Service

Se a validação deve ocorrer antes da criação do objeto, use DTOs e @Valid.

Se a validação deve ocorrer no momento da criação do objeto, use Assert do Spring.

Top comments (0)