TransWikia.com

Diferencia entre @RequestParam y @RequestBody

Stack Overflow en español Asked by Gonzalo on November 24, 2021

Estoy mirando la documentacion en Spring acerca de @RequestParam y @RequestBody donde uno usa el POST, y el otro el GET para poder trabajar con controladores, modelos, etc, pero no puedo entender la diferencia.
Alguien lo podria explicar facilmente para entenderlo por favor, me es muy dificil que es lo que dicen por Internet y sus ejemplos? Gracias.

Codigo a modo de ejemplo:

public void handle(@RequestBody String body, Writer writer) throws IOException {
  writer.write(body);
}

2 Answers

@RequestParameters representa uno o mas parametros que sera enviado por la url utilizando HTTP GET.

Suponiendo que tienes un metodo que recibe los siguientes parametros:

@GetMapping(value = "/api/usuario/existe")
public Boolean verificarUsuarioExiste(@RequestParameter String usuario)

Entonces en la url seria:

http://localhost/api/usuario/existe?usuario=einer

Puedes especificar cuantos parametros necesites:

@GetMapping(value = "/api/usuario/existe")
    public Boolean verificarUsuarioExiste(@RequestParameter String usuario, @RequestParameters int nivelAdministrativo)

Url:

 http://localhost/api/usuario/existe?usuario=einer&nivelAdministrativo=3

Bono: Si necesitas enviar muchos parametros, entonces puedes simplificar el metodo utilizando una clase que represente los parametros que enviaras por la url. Nota que no es requerido utilizar @RequestParamaters:

public class VerificacionUsuarioParams
{
  private String usuario
  private int nivelAdministrativo;

  public String getUsuario() { return usuario; };
  public void setUsuario(String usuario) { this.usuario = usuario; };
  public int getNivelAdministrativo() { return this.nivelAdministrativo; };
  public void setNivelAdministrativo(int nivel) { this.nivelAdministrativo =  nivel; };
}

En el metodo:

@GetMapping(value = "/api/usuario/existe")
        public Boolean verificarUsuarioExiste(VerificacionUsuarioParams parametros)

@RequestBody son los datos que se envian en el cuerpo de la petición utilizando HTTP POST. En otras palabras, la información de los datos va junto con la información de toda la peticion, no en la url. Por lo que si cambias el metodo anterior a @RequestBody e igual envias los parametros por la url, la data no sera bindiada.

Para que le metodo reciba la info, utilizas POST ya sea por un form:

<form action="/api/usuario/existe" method="post">
 <input type="text" name="usuario" />

 <button type="submit">Enviar</button>
</form>

O por fetch especificando los parametros en la propiedad body y method como POST:

fetch(url,{
     method:"POST",
     body: "einer", // data del parametro usuario
     headers:{
    'Content-Type':'application/json',
}})

Answered by Einer on November 24, 2021

Lo primero es tener bien clara la diferencia de lo que es un parámetro de lo que es el cuerpo de la petición.

En HTTP, una petición (request) es el envío de un mensaje de una aplicación cliente cliente a otra aplicación servidora. Ese mensaje se compone de

  • Cabeceras: Metadatos del mensaje
  • Cuerpo: Contenido del mensaje

Ese mensaje se envía a una URL utilizando un método (GET, POST, etc.)

Por lo que tenemos 3 sitios donde se puede incluir información (Cabeceras, Cuerpo y la propia URL de destino del mensaje)

¿Qué es un parámetro?: Un parámetro es cada uno de los pares clave valor que se especifican en la URL. Si tu URL donde mandas el mensaje es http://www.miweb.com/index.php?name=john&surname=doe estás mandando dos parámetros, uno con clave name y valor john y otro con clave surname y valor doe.

¿Qué es el cuerpo?: El cuerpo es el resto de los datos que van dentro del mensaje, es decir, no van en la URL como el parámetro. Existen varias formas de codificar estos valores. Para especificar la codificación, lo puedes hacer añadiendo una cabecera con clave "Content-Type" y después el tipo de codificación que vas a utilizar.

Por ejemplo, si utilizas: Content-Type: application/x-www-form-urlencoded el cuerpo contendría algo así:

name=john&surname=doe

Pero si utilizases Content-Type: application/json el cuerpo contendría algo así:

{"name":"john","surname":"doe"}

Como ves la información es la misma, pero codificada de diferente forma.

Ya volviendo a Spring, ¿para qué nos valen estas anotaciones?

  • La anotación @RequestParam nos sirve para acceder al valor de uno de los parámetros. Por ejemplo si tenemos este método:
public String getData(@RequestParam name, @RequestParam surname) { ... }

En este caso Spring automáticamente inyectaría en la variable name el valor del parámetro name (recordemos que los parámetros vienen de la URL) y en la variable surname el valor parámetro surname.

  • La anotación @RequestBody nos sirve para deserializar un objeto completo a partir del cuerpo de la petición. Es decir si tenemos esta clase:
public class Person {
  private String name;
  private String surname;
  // Getters+setters, etc.
}

y tenemos este método:

public String getData(@RequestBody Person person) { ... }

En este caso Spring nos inyectaría en la variable person un objeto de la clase Person con los atributos name y surname informados con lo que nos venga en el cuerpo de esa petición.

Aquí Spring hace muchas cosas, porque primero mira el Content-type para determinar el tipo de codificación, después decodifica esos datos, crea una instancia nueva de la clase Person y llama a los setters correspondientes para informar sus atributos.

En general, al mandar un mensaje con GET no se manda cuerpo, por lo que los datos se suelen pasar en la URL, por lo que para obtenerlos se usaría @RequestParam.

Para otro tipo de métodos, los datos se suelen mandar en el cuerpo y/o como parámetros. Según lo que queramos obtener, deberemos usar @RequestParam o @RequestBody.

Si inspeccionas una petición con las herramientas de desarrollo de tu navegador vas a ver algo así:

introducir la descripción de la imagen aquí

En los recuadros rojos vas a ver, que se aprecian:

  • La URL con sus parámetros
  • El método usado
  • El Content-Type, una de las posibles cabeceras que se pueden utilizar en la que indicamos la codificación del cuerpo de la petición.
  • En Query String Parameters tienes los valores que se pueden extraer con @RequestParam, es decir, los parámetros.
  • En Form Data tienes los valores que se pueden extraer con @RequestBody, es decir, el cuerpo de la petición.

Más info:

Answered by ordago on November 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP