DEV Community

Cover image for Jakarta Validation
Uiratan Cavalcante
Uiratan Cavalcante

Posted on

Jakarta Validation

Jakarta Validation (Bean Validation) no Spring Boot 🚀

O Jakarta Validation, anteriormente conhecido como Bean Validation, é um padrão para validar objetos Java de forma declarativa. Ele permite adicionar restrições diretamente nos atributos de classes, sem necessidade de código manual para verificações.

No Spring Boot, a validação com Jakarta Validation é integrada automaticamente ao Spring MVC e ao Spring Data JPA, facilitando a validação de DTOs (Data Transfer Objects) e entidades.


📌 1. Como Funciona?

Jakarta Validation usa anotações para definir regras de validação diretamente nos atributos de uma classe.

Exemplo de Classe com Validação

import jakarta.validation.constraints.*;

public record AutorRequest(
    @NotBlank(message = "O nome é obrigatório") 
    String nome,

    @NotBlank(message = "O email é obrigatório") 
    @Email(message = "O email deve ter um formato válido") 
    String email,

    @NotBlank(message = "A descrição é obrigatória") 
    @Size(max = 400, message = "A descrição não pode ter mais de 400 caracteres") 
    String descricao
) {
    public Autor toModel() {
        return new Autor(nome, email, descricao);
    }
}
Enter fullscreen mode Exit fullscreen mode

O que acontece aqui?

  • @NotBlank → Garante que o valor não seja nulo nem vazio.
  • @Email → Valida se o email tem um formato correto.
  • @Size(max = 400) → Limita a descrição a 400 caracteres.

Se algum desses critérios não for atendido, o Spring automaticamente retorna 400 Bad Request.


📌 2. Como Ativar a Validação no Spring Boot?

O Spring Boot já possui suporte nativo, mas você deve garantir que a dependência está presente no pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Agora, no seu Controller, basta usar @Valid para ativar a validação:

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

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

    private final AutorService autorService;

    public AutorController(AutorService autorService) {
        this.autorService = autorService;
    }

    @PostMapping
    public ResponseEntity<Void> cadastrar(@RequestBody @Valid AutorRequest request) {
        autorService.cadastrarAutor(request);
        return ResponseEntity.ok().build();
    }
}
Enter fullscreen mode Exit fullscreen mode

Agora, qualquer requisição inválida será automaticamente rejeitada pelo Spring.


📌 3. Principais Anotações do Jakarta Validation

🛠 Validações Simples

Anotação Descrição
@NotNull Não permite um valor nulo, porém permite um valor vazio.
@NotEmpty Assim como a @NotNull, não permite valor nulo e além disso seu tamanho deve ser maior que zero. Espaços em brancos são levados em conta na verificação de tamanho do valor.
@NotBlank Assim como a @NotEmpty, não permite valor nulo e o comprimento (sem considerar espaços em branco) deve ser maior que zero.
@Size(min = X, max = Y) Define o tamanho mínimo e/ou máximo de um campo String ou List.
@Email Valida se a string tem um formato de email válido.
@Pattern(regexp = "...") Valida se a string segue um padrão regex.

🛠 Validações Numéricas

Anotação Descrição
@Positive O número deve ser positivo (> 0).
@PositiveOrZero O número deve ser positivo ou zero.
@Negative O número deve ser negativo (< 0).
@NegativeOrZero O número deve ser negativo ou zero.
@Min(X) O número deve ser maior ou igual a X.
@Max(Y) O número deve ser menor ou igual a Y.
@Digits(integer = X, fraction = Y) Define um número com até X casas inteiras e Y casas decimais.

🛠 Validações Específicas

Anotação Descrição
@AssertTrue O valor deve ser true.
@AssertFalse O valor deve ser false.
@Future A data deve ser no futuro.
@Past A data deve ser no passado.

📌 4. Personalizando Mensagens de Erro

Você pode personalizar mensagens nas anotações:

@Size(max = 400, message = "A descrição não pode ter mais de 400 caracteres")
private String descricao;
Enter fullscreen mode Exit fullscreen mode

Ou usar um arquivo de mensagens (messages.properties):

📄 resources/messages.properties

autor.nome.notblank = O nome é obrigatório
autor.email.notblank = O email é obrigatório
autor.email.invalid = O email deve ter um formato válido
autor.descricao.size = A descrição não pode ter mais de 400 caracteres
Enter fullscreen mode Exit fullscreen mode

E no código:

@NotBlank(message = "{autor.nome.notblank}")
private String nome;
Enter fullscreen mode Exit fullscreen mode

📌 5. Tratamento Global de Erros

O Spring Boot retorna um erro padrão, mas você pode criar um Handler Global para personalizar a resposta:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class ValidacaoExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();

        for (FieldError error : ex.getBindingResult().getFieldErrors()) {
            errors.put(error.getField(), error.getDefaultMessage());
        }

        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
    }
}
Enter fullscreen mode Exit fullscreen mode

Agora, se houver erro, a API retorna um JSON estruturado:

{
    "nome": "O nome é obrigatório",
    "email": "O email deve ter um formato válido",
    "descricao": "A descrição não pode ter mais de 400 caracteres"
}
Enter fullscreen mode Exit fullscreen mode

📌 6. Validação Customizada com @Constraint

Se precisar criar uma validação própria, use @Constraint:

Exemplo: Validar domínio de email

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = EmailEmpresaValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EmailEmpresa {
    String message() default "O email deve pertencer ao domínio @empresa.com";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
Enter fullscreen mode Exit fullscreen mode

Classe EmailEmpresaValidator

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

public class EmailEmpresaValidator implements ConstraintValidator<EmailEmpresa, String> {

    @Override
    public boolean isValid(String email, ConstraintValidatorContext context) {
        return email != null && email.endsWith("@empresa.com");
    }
}
Enter fullscreen mode Exit fullscreen mode

Uso na Classe de Request

@EmailEmpresa
private String email;
Enter fullscreen mode Exit fullscreen mode

Agora, apenas emails @empresa.com serão aceitos!


📌 Conclusão

Validações declarativas fáceis de usar

Mensagens de erro personalizadas

Tratamento global de erros

Validações customizadas para regras específicas

Com Jakarta Validation, sua API fica mais robusta e segura! 🚀


Para obter mais informações sobre o Jakarta Validation, você pode consultar os seguintes recursos oficiais:

Esses links fornecem acesso à documentação completa, especificações e recursos adicionais para auxiliar no uso do Jakarta Validation em suas aplicações Java.

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay