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
}
}
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());
}
}
✅ 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";
}
}
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);
}
}
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();
}
}
✅ 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)