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.

Top comments (0)