Как работает аннотация Spring @ResponseBody в этом примере приложения RESTful?
у меня есть метод, который аннотируется следующим образом:
/**
* Provide a list of all accounts.
*/
// TODO 02: Complete this method. Add annotations to respond
// to GET /accounts and return a List<Account> to be converted.
// Save your work and restart the server. You should get JSON results when accessing
// http://localhost:8080/rest-ws/app/accounts
@RequestMapping(value="/orders", method=RequestMethod.GET)
public @ResponseBody List<Account> accountSummary() {
return accountManager.getAllAccounts();
}
так что я знаю, что по этой аннотации:
@RequestMapping(value="/orders", method=RequestMethod.GET)
этот метод дескриптор GET HTTP-запросы к ресурсу, представленному URL / orders.
этот метод вызывает объект DAO, который возвращает список.
здесь счета представляющий пользователя в системе и имеет некоторые поля, которые представляют этот пользователь, что-то типа:
public class Account {
@Id
@Column(name = "ID")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long entityId;
@Column(name = "NUMBER")
private String number;
@Column(name = "NAME")
private String name;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name = "ACCOUNT_ID")
private Set<Beneficiary> beneficiaries = new HashSet<Beneficiary>();
...............................
...............................
...............................
}
мой вопрос: как именно это делает @ResponseBody
работа аннотации?
он расположен перед возвращено List<Account>
объект, так что я думаю, что он относится к этому списку. В документации курса указано, что эта аннотация выполняет функцию:
убедитесь, что результат будет записан в ответ HTTP с помощью HTTP Конвертер сообщений (вместо MVC Вид.)
а также чтение официальной весенней документации: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html
кажется, что он принимает List<Account>
объект и помещает его в Http Response
. Это правильно или я неправильно понял?
написано в комментарии к предыдущему accountSummary()
способ есть:
вы должны получить JSON результаты при доступе http://localhost:8080/rest-ws/app/accounts
так что же это значит? Означает ли это, что и Http Response
? Или что?
если это утверждение верно, то где это указано, что объект будет автоматически преобразован в ? Является ли стандартный формат принят, когда @ResponseBody
аннотация используется или указывается в другом месте?
4 ответа:
во-первых, аннотация не комментировать
List
. Он аннотирует метод, так же какRequestMapping
делает. Ваш код эквивалентен@RequestMapping(value="/orders", method=RequestMethod.GET) @ResponseBody public List<Account> accountSummary() { return accountManager.getAllAccounts(); }
теперь то, что аннотация означает, что возвращаемое значение метода будет составлять тело ответа HTTP. Конечно, HTTP-ответ не может содержать объекты Java. Таким образом, этот список учетных записей преобразуется в формат, подходящий для приложений REST, обычно JSON или XML.
выбор формата зависит от установленных конвертеров сообщений, от значений
produces
атрибут аннотации RequestMapping и типа контента, который принимает клиент (который доступен в заголовках HTTP-запросов). Например, если запрос говорит, что он принимает XML, но не JSON, и установлен конвертер сообщений, который может преобразовать список в XML, то XML будет возвращен.
первое, что нужно понять, это разница в архитектуре.
один конец у вас есть архитектура MVC, которая основана на вашем обычном веб-приложении, используя веб-страницы, и браузер делает запрос на страницу:
Browser <---> Controller <---> Model | | +-View-+
браузер делает запрос, контроллер (@Controller) получает модель (@Entity) и создает представление (JSP) из модели, и представление возвращается обратно клиенту. Это базовая архитектура веб-приложения.
On с другой стороны, у вас есть спокойная архитектура. В этом случае нет никакого представления. Контроллер только отправляет обратно модель (или представление ресурсов, в более спокойных терминах). Клиент может быть приложением JavaScript, серверным приложением Java, любым приложением, в котором мы предоставляем наш REST API. С помощью этой архитектуры клиент решает, что делать с этой моделью. Возьмем, к примеру, Twitter. Twitter Как web (REST) API, что позволяет нашим приложениям использовать его API для получения таких вещей, как статус обновления, так что мы можем использовать его, чтобы поместить эти данные в наше приложение. Эти данные будут поступать в некотором формате, например JSON.
это, как говорится, при работе с Spring MVC, он был впервые построен для обработки базовой архитектуры веб-приложений. Существуют различные варианты сигнатур методов, которые позволяют создавать представление из наших методов. Метод может возвращать a
ModelAndView
где мы явно создаем его, или есть неявные способы, где мы можем вернуть некоторый произвольный объект, который получает набор в атрибуты модели. Но в любом случае, где-то в цикле запрос-ответ будет создано представление.но когда мы используем
@ResponseBody
, мы говорим, что мы не хотим смотреть производства. Мы просто хотим отправить возвращаемый объект как тело, в любом формате, который мы указываем. Мы не хотели бы, чтобы это был сериализованный объект Java (хотя это возможно). Так что да, он должен быть преобразован в какой-то другой общий тип (Этот тип обычно рассматривается через согласование контента-см. ссылку ниже.) Честно говоря, я не очень много работаю с весной, хотя я балуюсь с ней здесь и там. Обычно я использую@RequestMapping(..., produces = MediaType.APPLICATION_JSON_VALUE)
чтобы установить тип контента, но, возможно, JSON по умолчанию. Не цитируйте меня, но если вы получаете JSON, и вы не указали
produces
, то, возможно, это по умолчанию. JSON-это не единственный формат. Например, вышеизложенное может быть легко отправлено в XML, но вам нужно будет иметьproduces
доMediaType.APPLICATION_XML_VALUE
и я считаю, что вам нужно настроитьHttpMessageConverter
для JAXB. Что касается JSONMappingJacksonHttpMessageConverter
настроено, когда у нас есть Джексон на пути к классам.Я бы взял некоторое время, чтобы узнать о Содержание Переговоров. Это очень важная часть отдыха. Это поможет вам узнать о различных форматах ответа и как сопоставить их с вашими методами.
как упоминалось JB Nizet,
@RequestMapping(value="/orders", method=RequestMethod.GET) @ResponseBody public List<Account> accountSummary() { return accountManager.getAllAccounts(); }
и
@RequestMapping(value="/orders", method=RequestMethod.GET) public @ResponseBody List<Account> accountSummary() { return accountManager.getAllAccounts(); }
одинаковы. поскольку @ResponseBody аннотирует метод, а не список. @GMsoF - установленные здесь конвертеры сообщений можно использовать следующим образом.
@RequestMapping(value="/orders", method=RequestMethod.GET , produces={"application/json","application/xml"}) @ResponseBody public List<Account> accountSummary() { return accountManager.getAllAccounts(); }
спасибо :)
В дополнение к этому, тип возвращаемого значения определяется
что HTTP-запрос говорит, что он хочет - в его заголовке Accept. Попробуйте посмотреть на первоначальный запрос, как посмотреть, что Accept установлен.
Что HttpMessageConverters Весна устанавливает. Spring MVC настроит конвертеры для XML (используя JAXB) и JSON, если библиотеки Jackson находятся на пути к классам.
Если есть выбор, он выбирает один - в этом примере, это оказывается, это JSON.
этой и в ходе заметки. Найдите заметки о конвертерах сообщений и согласовании содержимого.