En el ecosistema de Spring MVC, la correcta gestión de los datos de entrada es fundamental para construir APIs robustas. Las anotaciones @RequestParam, @RequestBody y otras variantes permiten mapear la información proveniente del cliente directamente a objetos o variables en el controlador.
Uso detallado de @RequestParam
Esta anotación se utiliza principalmente para extraer parámetros de consulta (query params) de la URL o datos de formularios codificados como application/x-www-form-urlencoded.
Atributos principales
- value / name: Define el nombre del parámetro en la petición. Si no se especifica, Spring buscará un parámetro que coincida exactamente con el nombre de la variable en el método.
- required: Un booleano que indica si el parámetro es obligatorio. Por defecto es
true. Si el parámetro falta, el servidor responderá con un error 400. Para manejar valores nulos de forma segura, se recomienda usar tipos de envoltorio (Wrapper classes) comoIntegeroLongen lugar de primitivos si se establece enfalse. - defaultValue: Permite asignar un valer predeterminado si el parámetro no está presente en la solicitud.
Cuando se envían múltiples valores para una misma clave (ej. ?id=10&id=20), Spring puede capturarlos en arreglos o colecciones:
@GetMapping("/buscar")
public String filtrarProductos(@RequestParam(name = "categoria", defaultValue = "general") String cat,
@RequestParam(name = "ids") List<Long> identificadores) {
// Procesa la lista de IDs y la categoría
return "Resultados para: " + cat;
}
Otras anotaciones para datos de entrada
@PathVariable
Se utiliza para extraer valores directamente de la estructura de la URI. Es común en servicios RESTful para identificar recursos específicos.
@GetMapping("/cliente/{codigo}")
public ResponseEntity<Cliente> obtenerCliente(@PathVariable("codigo") String idCliente) {
// Lógica de búsqueda
}
@CookieValue y @RequestHeader
Permiten acceder a las cookies del navegador y a las cabeceras HTTP respectivamente sin necesidad de manipular el objeto HttpServletRequest manualmente.
@GetMapping("/ajustes")
public void leerConfiguracion(@CookieValue(value = "pref_idioma", defaultValue = "es") String idioma,
@RequestHeader("User-Agent") String agenteUsuario) {
// Uso de cabeceras y cookies
}
@ModelAttribute
Mapea parámetros de una petición directamente a un objeto Java (Command Object). Es extremadamente útil en aplicaciones que manejan formularios web complejos, ya que realiza el binding de múltiples campos automáticamente.
Comparativa: @RequestBody vs @RequestParam
La diferencia fundamental radica en el origen de los datos y el tipo de contenido (Content-Type):
- @RequestParam: Lee parámetros de la URL o de un cuerpo de formulario estándar. Es el estándar para peticiones
GET. - @RequestBody: Lee el cuerpo completo de la petición (body) y lo deserializa utilizando convertidores de mensajes (como Jackson para JSON). Es indispensable para manejar datos en formato
application/jsonoapplication/xmlen métodosPOSToPUT.
Escenarios comunes en peticiones POST
El comportamiento de estas anotaciones varía según cómo el cliente envíe los datos:
- Si el backend usa @RequestBody:
- Funciona correctamente con JSON (
application/json). - Falla si se intenta enviar datos vía
form-dataa menos que se configure un conversor específico.
- Funciona correctamente con JSON (
- Si el backend usa @RequestParam:
- Ideal para
x-www-form-urlencoded. - Si se envía un JSON, Spring no podrá mapearlo automáticamente a los parámetros individuales, a menos que se pasen como cadenas de texto simples en la URL.
- Ideal para
- Sin anotacionse:
- Si pasas un objeto complejo sin anotar, Spring intentará tratarlo como un
@ModelAttribute, buscando parámetros que coincidan con los atributos del objeto.
- Si pasas un objeto complejo sin anotar, Spring intentará tratarlo como un
@PostMapping("/registro")
public ResponseEntity<String> crearCuenta(@RequestBody UsuarioDTO datosUsuario) {
// Procesa el JSON recibido en el cuerpo de la petición
return ResponseEntity.ok("Usuario creado");
}
@PostMapping("/actualizar-estado")
public void cambiarEstado(@RequestParam("id") Long id, @RequestParam("activo") boolean activo) {
// Procesa parámetros enviados vía formulario o URL
}