Как работает аннотация 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 68

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. Что касается JSON MappingJacksonHttpMessageConverter настроено, когда у нас есть Джексон на пути к классам.

Я бы взял некоторое время, чтобы узнать о Содержание Переговоров. Это очень важная часть отдыха. Это поможет вам узнать о различных форматах ответа и как сопоставить их с вашими методами.

как упоминалось 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();
}

спасибо :)

В дополнение к этому, тип возвращаемого значения определяется

  1. что HTTP-запрос говорит, что он хочет - в его заголовке Accept. Попробуйте посмотреть на первоначальный запрос, как посмотреть, что Accept установлен.

  2. Что HttpMessageConverters Весна устанавливает. Spring MVC настроит конвертеры для XML (используя JAXB) и JSON, если библиотеки Jackson находятся на пути к классам.

Если есть выбор, он выбирает один - в этом примере, это оказывается, это JSON.

этой и в ходе заметки. Найдите заметки о конвертерах сообщений и согласовании содержимого.