CodeGym /Cursos /Módulo 5. Spring /Uso de la anotación @Valid para validar solicitudes

Uso de la anotación @Valid para validar solicitudes

Módulo 5. Spring
Nivel 8 , Lección 2
Disponible

La validación "sin intervención humana" es como tener un robot diligente que revisa tu correo antes de que lo leas: descarta el spam y marca los mensajes importantes. De forma análoga, la anotación @Valid te permite automatizar la comprobación de los datos entrantes en tus controladores y servicios.

Aspectos principales de @Valid

  • Forma parte de la especificación Bean Validation API.
  • Comprueba automáticamente si los datos entrantes cumplen con las anotaciones de validación declaradas en los DTO (Data Transfer Object) u otros objetos.
  • Ayuda a simplificar y centralizar la validación de datos, manteniendo tu código limpio y legible.

Ejemplo sencillo: recibes un JSON como cuerpo de una petición POST y necesitas que el campo "email" sea obligatorio y tenga formato de email. En lugar de validar manualmente (por ejemplo, con if), con @Valid y unas cuantas anotaciones de validación todo se hace automáticamente.


¿Cómo usar @Valid en los controladores?

Paso 1. Declarar el DTO

Empecemos creando la clase DTO. DTO (Data Transfer Object) es el objeto que se usa para transferir datos, por ejemplo, del cliente al servidor.


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

public class UserDTO {

    @NotNull(message = "El nombre de usuario no puede estar vacío.")
    @Size(min = 2, max = 30, message = "El nombre de usuario debe tener entre 2 y 30 caracteres.")
    private String username;

    @NotNull(message = "El email es obligatorio.")
    @Email(message = "Formato de email incorrecto.")
    private String email;

    public UserDTO() {}

    public UserDTO(String username, String email) {
        this.username = username;
        this.email = email;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Aquí usamos:

  • @NotNull — para asegurarnos de que el campo no esté vacío.
  • @Size — para limitar la longitud de la cadena.
  • @Email — para comprobar que el email es correcto.

Con el campo aclarado, seguimos al siguiente paso.

Paso 2. Crear el REST-controller

Ahora usamos la anotación @Valid en el controller para la validación automática de los datos entrantes.


import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;

@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO userDTO) {
        // Si los datos son válidos, la ejecución llega aquí.
        return new ResponseEntity<>("Usuario creado con éxito", HttpStatus.CREATED);
    }
}
  • @RestController indica que esta clase es un REST-controller.
  • @RequestBody — convierte el JSON en el objeto UserDTO.
  • @Valid — lanza la validación que comprueba los campos de UserDTO.

Si los datos entrantes son válidos, el cuerpo de la petición se convierte con éxito en el objeto y el servidor devuelve HTTP 201 (Created). Si la validación falla, Spring lanzará automáticamente la excepción MethodArgumentNotValidException.

Paso 3. Añadir mensajes personalizados

Cada anotación de validación en UserDTO contiene el parámetro message, que indica el texto del error. Por ejemplo, si el campo email no cumple el formato, el cliente recibirá el mensaje "Formato de email incorrecto.".


Ejemplo de aplicación usando @Valid

Juntamos todo en una pequeña aplicación.

Código principal de la aplicación

DTO:


public class UserDTO {
    @NotNull(message = "El nombre de usuario no puede estar vacío.")
    @Size(min = 2, max = 30, message = "El nombre de usuario debe tener entre 2 y 30 caracteres.")
    private String username;

    @NotNull(message = "El email es obligatorio.")
    @Email(message = "Formato de email incorrecto.")
    private String email;

    // Getters, setters y constructor
}

Controller:


@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO userDTO) {
        return new ResponseEntity<>("Usuario creado con éxito", HttpStatus.CREATED);
    }
}

application.properties:


server.port=8080

¿Qué pasa si los datos no son válidos?

Al enviar datos incorrectos, Spring devolverá automáticamente HTTP 400 (Bad Request) con un mensaje de error en formato JSON:


{
    "timestamp": "2023-10-01T12:34:56.789+00:00",
    "status": 400,
    "error": "Bad Request",
    "message": "Formato de email incorrecto.",
    "path": "/api/users"
}

Errores comunes

  1. Falta la dependencia de Bean Validation en pom.xml. En el proyecto puede faltar la dependencia necesaria. Asegúrate de que en tu pom.xml está añadido el módulo de Bean Validation:
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    
  2. El cuerpo de la petición no se convierte en DTO. Si olvidas indicar @RequestBody, el JSON simplemente no se reconocerá. Siempre recuerda esa anotación.
  3. Import incorrecto de la anotación @Valid. Asegúrate de usar jakarta.validation.Valid (o javax.validation.Valid en versiones antiguas), y no alguna variante de librerías externas.
  4. Falta el manejo de excepciones. Spring puede lanzar la excepción MethodArgumentNotValidException, que si no se maneja dará mensajes feos y confusos al usuario.

Aplicaciones prácticas

La validación con @Valid se usa mucho en proyectos reales para:

  • Comprobar automáticamente los datos que vienen de los clientes.
  • Evitar errores en etapas tempranas, antes de que los datos lleguen a la lógica de negocio o a la base de datos.
  • Mejorar la legibilidad y mantenibilidad del código.

En las entrevistas pueden pedirte que describas cómo implementas validación en Spring, y aún mejor — que escribas una operación REST sencilla con @Valid. Dominar esta herramienta te dará una ventaja importante.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION