Anotaciones @RequestBody y @ResponseBody en primavera

138

¿Alguien puede explicar las anotaciones @RequestBodyy @ResponseBodyen la primavera 3? ¿Para qué son? Cualquier ejemplo sería genial.

León
fuente

Respuestas:

218

Hay una sección completa en los documentos llamada 16.3.3.4 Asignación del cuerpo de la solicitud con la anotación @RequestBody . Y uno llamado 16.3.3.5 Mapear el cuerpo de la respuesta con la anotación @ResponseBody . Le sugiero que consulte esas secciones. También relevante: @RequestBodyjavadocs, @ResponseBodyjavadocs

Los ejemplos de uso serían algo como esto:

Usando una biblioteca de JavaScript como JQuery, publicaría un objeto JSON como este:

{ "firstName" : "Elmer", "lastName" : "Fudd" }

Su método de controlador se vería así:

// controller
@ResponseBody @RequestMapping("/description")
public Description getDescription(@RequestBody UserStats stats){
    return new Description(stats.getFirstName() + " " + stats.getLastname() + " hates wacky wabbits");
}

// domain / value objects
public class UserStats{
    private String firstName;
    private String lastName;
    // + getters, setters
}
public class Description{
    private String description;
    // + getters, setters, constructor
}

Ahora, si tiene Jackson en su classpath (y tiene una <mvc:annotation-driven>configuración), Spring convertiría el JSON entrante en un objeto UserStats del cuerpo de la publicación (porque agregó la @RequestBodyanotación) y serializaría el objeto devuelto a JSON (porque agregó el @ResponseBodyanotación). Entonces el navegador / cliente vería este resultado JSON:

{ "description" : "Elmer Fudd hates wacky wabbits" }

Vea esta respuesta anterior mía para un ejemplo de trabajo completo: https://stackoverflow.com/a/5908632/342852

Nota: RequestBody / ResponseBody, por supuesto, no está limitado a JSON, ambos pueden manejar múltiples formatos, incluyendo texto sin formato y XML, pero JSON es probablemente el formato más utilizado.


Actualizar

Desde Spring 4.x, por lo general no lo usará @ResponseBodya nivel de método, sino @RestControllera nivel de clase, con el mismo efecto.

Aquí hay una cita de la documentación oficial de Spring MVC :

@RestControlleres una anotación compuesta que está meta-anotada con @Controllere @ResponseBodypara indicar un controlador cuyo método hereda la @ResponseBodyanotación de nivel de tipo y, por lo tanto, escribe directamente en el cuerpo de la respuesta frente a la resolución de la vista y la representación con una plantilla HTML.

Sean Patrick Floyd
fuente
En su respuesta vinculada, utilizó la @ResponseBodyanotación en el parámetro, no en el método. Recibo errores al intentar ponerlo en el método, así que supongo que su otra respuesta es correcta. Creo que deberías haberlo hecho getDescription(@RequestBody UserStats stats)arriba.
Patrick
3
@Patrick no, @RequestBodyestá en el parámetro, @ResponseBodyestá en el método. diferencia importante!
Sean Patrick Floyd el
1
@SeanPatrickFloyd Lo siento, no quise mencionarlo @ResponseBodyen absoluto. Como acabas de decir, @RequestBodyva el parámetro, ¿verdad? Pero en la respuesta anterior, lo tienes en el método.
Patrick
1
@SeanPatrickFloyd @RequestBodytodavía se requiere, @ResponseBodyestá implícito cuando se usa @RestController. ¡Por favor corrija su respuesta, tiene demasiados votos a favor para ser falsos!
Sumit Jain
@SumitJain para ser justos: esta respuesta ya existía antes @RestControllery se modificó cuando se presentó
Sean Patrick Floyd el
32

@RequestBody : la anotación que indica un parámetro de método debe estar vinculada al cuerpo de la solicitud HTTP.

Por ejemplo:

@RequestMapping(path = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
    writer.write(body);
}

La anotación @ResponseBody se puede poner en un método e indica que el tipo de retorno debe escribirse directamente en el cuerpo de la respuesta HTTP (y no colocarse en un Modelo o interpretarse como un nombre de vista).

Por ejemplo:

@RequestMapping(path = "/something", method = RequestMethod.PUT)
public  @ResponseBody String helloWorld() {
    return "Hello World";
}  

Alternativamente, podemos usar la anotación @RestController en lugar de la @Controlleranotación. Esto eliminará la necesidad de usar @ResponseBody.

para más detalles

Premraj
fuente
5

A continuación se muestra un ejemplo de un método en un controlador Java.

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public HttpStatus something(@RequestBody MyModel myModel) 
{
    return HttpStatus.OK;
}

Al usar la anotación @RequestBody obtendrá sus valores asignados con el modelo que creó en su sistema para manejar cualquier llamada específica. Mientras usa @ResponseBody puede enviar cualquier cosa al lugar desde donde se generó la solicitud. Ambas cosas se asignarán fácilmente sin escribir ningún analizador personalizado, etc.

AbdusSalam
fuente
1
package com.programmingfree.springshop.controller;

import java.util.List;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.programmingfree.springshop.dao.UserShop;
import com.programmingfree.springshop.domain.User;


@RestController
@RequestMapping("/shop/user")
public class SpringShopController {

 UserShop userShop=new UserShop();

 @RequestMapping(value = "/{id}", method = RequestMethod.GET,headers="Accept=application/json")
 public User getUser(@PathVariable int id) {
  User user=userShop.getUserById(id);
  return user;
 }


 @RequestMapping(method = RequestMethod.GET,headers="Accept=application/json")
 public List<User> getAllUsers() {
  List<User> users=userShop.getAllUsers();
  return users;
 }


}

En el ejemplo anterior, van a mostrar todos los detalles de identificación de usuario y particulares, ahora quiero usar tanto la identificación como el nombre,

1) localhost: 8093 / plejson / shop / user <--- este enlace mostrará todos los detalles del usuario
2) localhost: 8093 / plejson / shop / user / 11 <---- si uso 11 en el enlace significa, lo hará mostrar detalles particulares del usuario 11

ahora quiero usar tanto id como nombre

localhost: 8093 / plejson / shop / user / 11 / raju <----------------- así significa que podemos usar cualquiera en esto, por favor ayúdenme ... .

usuario5409646
fuente
Corrija el formato de la respuesta y la muestra de código.
Maciej Lach
Describa cómo este código ayuda al interlocutor. Gracias.
Leonid Glanz
programación
free.com
programación- free.com/ 2014/ 03/… ....................................... .................................................. ..... ve a través de este enlace y te lo agradecerá
user5409646