Аннотации @RequestBody и @ResponseBody в Spring

140

Может кто - то объяснить @RequestBodyи @ResponseBodyаннотации в Spring 3? Для чего они? Любые примеры были бы замечательными.

Лео
источник

Ответы:

222

В документации есть целый раздел под названием 16.3.3.4 Сопоставление тела запроса с аннотацией @RequestBody . И один из них называется 16.3.3.5 Отображение тела ответа с аннотацией @ResponseBody . Предлагаю вам ознакомиться с этими разделами. Также актуально: @RequestBodyjavadocs, @ResponseBodyjavadocs

Примеры использования будут примерно такими:

Используя JavaScript-библиотеку, такую ​​как JQuery, вы разместите JSON-объект следующим образом:

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

Ваш метод контроллера будет выглядеть так:

// 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
}

Теперь, если у вас есть Джексон в вашем пути к классам (и у вас есть <mvc:annotation-driven>настройка), Spring преобразует входящий JSON в объект UserStats из тела сообщения (потому что вы добавили @RequestBodyаннотацию) и сериализует возвращенный объект в JSON (потому что вы добавили @ResponseBodyаннотация). Таким образом, браузер / клиент увидит этот результат JSON:

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

См. Этот мой предыдущий ответ для полного рабочего примера: https://stackoverflow.com/a/5908632/342852

Примечание. RequestBody / ResponseBody, конечно, не ограничивается JSON, оба могут обрабатывать несколько форматов, включая простой текст и XML, но JSON, вероятно, является наиболее часто используемым форматом.


Обновить

Начиная с Spring 4.x, вы обычно используете не @ResponseBodyна уровне метода, а @RestControllerна уровне класса с тем же эффектом.

Вот цитата из официальной документации Spring MVC :

@RestControllerэто состоит аннотацию , что само по себе мета-аннотированный с @Controllerи @ResponseBodyуказать контроллер каждый метод которого наследует тип уровня @ResponseBodyаннотацию и, следовательно, пишет прямо в тело ответа по сравнению с разрешением просмотра и рендеринга с шаблоном HTML.

Шон Патрик Флойд
источник
В связанном ответе вы использовали @ResponseBodyаннотацию к параметру, а не к методу. Я получаю ошибки при попытке применить это к методу, поэтому предполагаю, что ваш другой ответ верен. Я думаю, вам следовало бы getDescription(@RequestBody UserStats stats)выше.
Патрик
4
@Patrick нет, @RequestBodyэто параметр, @ResponseBodyметод. важное отличие!
Шон Патрик Флойд
1
@SeanPatrickFloyd Извините, я вообще не хотел упоминать @ResponseBody. Как вы только что сказали, @RequestBodyидет по параметру, верно? Но в приведенном выше ответе это есть в методе.
Патрик
1
@SeanPatrickFloyd @RequestBodyна самом деле все еще требуется, @ResponseBodyнеявно используется при использовании @RestController. Пожалуйста, исправьте свой ответ, слишком много голосов, чтобы быть ложным!
Sumit Jain
@SumitJain, если честно: этот ответ был раньше @RestControllerи был изменен, когда он был представлен
Шон Патрик Флойд,
32

@RequestBody : аннотация, указывающая, что параметр метода должен быть привязан к телу HTTP-запроса.

Например:

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

@ResponseBodyАннотация может быть помещена в метод и указывает, что тип возвращаемого значения должен быть записан прямо в тело ответа HTTP (а не помещен в модель или интерпретирован как имя представления).

Например:

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

В качестве альтернативы мы можем использовать аннотацию @RestController вместо @Controllerаннотации. Это избавит от необходимости использовать @ResponseBody.

Больше подробностей

Премрадж
источник
5

Ниже приведен пример метода в контроллере Java.

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

Используя аннотацию @RequestBody, вы получите свои значения, сопоставленные с моделью, которую вы создали в своей системе для обработки любого конкретного вызова. Используя @ResponseBody, вы можете отправить что угодно обратно в то место, откуда был сгенерирован запрос. Обе вещи будут легко сопоставлены без написания специального парсера и т. Д.

АбдусСалам
источник
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;
 }


}

В приведенном выше примере они будут отображать все данные о пользователях и конкретных идентификаторах, теперь я хочу использовать как идентификатор, так и имя,

1) localhost: 8093 / plejson / shop / user <--- эта ссылка будет отображать все данные пользователя
2) localhost: 8093 / plejson / shop / user / 11 <---- если я использую 11 в ссылке, значит, это будет отобразить детали конкретного пользователя 11

теперь я хочу использовать как идентификатор, так и имя

localhost: 8093 / plejson / shop / user / 11 / raju <----------------- это означает, что мы можем использовать здесь любой, пожалуйста, помогите мне .... .

user5409646
источник
Исправьте форматирование ответа и образца кода.
Maciej Lach
Пожалуйста, опишите, как этот код помогает спрашивающему. Спасибо.
Леонид Гланц
Programming-free.com/2014/03/… .................... пройдите по этой ссылке и получите ... спасибо
user5409646
программирование- free.com/2014/ 03/ … ....................................... .................................................. ..... пройдите по этой ссылке и получите спасибо
user5409646 05