Spring @ResponseBody注释如何在这个RESTful应用程序示例中工作?

时间:2015-02-21 13:28:26

标签: java json spring rest spring-mvc

我有一个以下列方式注释的方法:

/**
* 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)

此方法处理对 / orders 所代表的资源进行的 GET HTTP请求。

此方法调用返回列表的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结果写入HTTP响应   消息转换器(而不是MVC视图)。

还阅读官方的Spring文档: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

那究竟是什么意思呢?这是否意味着List<Account>方法返回的accountSummary()对象会自动转换为JSON格式,然后放入Http Response?或者是什么?

如果此断言为真,那么它在何处指定该对象将自动转换为JSON格式?使用@ResponseBody注释时是采用标准格式还是在其他地方指定?

5 个答案:

答案 0 :(得分:133)

首先,注释没有注释List。它注释方法,就像RequestMapping一样。您的代码等同于

@RequestMapping(value="/orders", method=RequestMethod.GET)
@ResponseBody
public List<Account> accountSummary() {
    return accountManager.getAllAccounts();
}

现在注释的含义是方法的返回值将构成HTTP响应的主体。当然,HTTP响应不能包含Java对象。因此,此帐户列表将转换为适合REST应用程序的格式,通常为JSON或XML。

格式的选择取决于安装的消息转换器,RequestMapping注释的produces attribute的值以及客户端接受的内容类型(在HTTP请求标头中可用)。例如,如果请求说它接受XML而不是JSON,并且安装了可以将列表转换为XML的消息转换器,那么将返回XML。

答案 1 :(得分:51)

要理解的第一个基本要素是架构的差异。

一端你有MVC架构,它基于你的普通网络应用程序,使用网页,浏览器请求页面:

Browser <---> Controller <---> Model
               |      |
               +-View-+

浏览器发出请求,控制器(@Controller)获取模型(@Entity),并从模型创建视图(JSP),视图返回给客户端。这是基本的Web应用程序架构。

另一方面,您拥有RESTful架构。在这种情况下,没有View。 Controller仅发送回模型(或资源表示,更多RESTful术语)。客户端可以是JavaScript应用程序,Java服务器应用程序,以及我们将REST API公开的任何应用程序。通过这种架构,客户端决定如何处理此模型。以Twitter为例。 Twitter作为Web(REST)API,允许我们的应用程序使用其API来获取状态更新等内容,以便我们可以使用它将这些数据放入我们的应用程序中。该数据将以某种格式出现,如JSON。

话虽如此,在使用Spring MVC时,它最初是为处理基本的Web应用程序架构而构建的。可能有不同的方法签名风格允许从我们的方法生成视图。该方法可以返回我们显式创建它的ModelAndView,或者有隐式方法可以返回一些被设置为模型属性的任意对象。但无论如何,在请求 - 响应周期的某个地方,都会产生一个视图。

但是当我们使用@ResponseBody时,我们说我们不希望生成视图。我们只想以我们指定的格式发送返回对象作为正文。我们不希望它成为序列化的Java对象(尽管可能)。所以是的,它需要转换为其他一些常见类型(这种类型通常通过内容协商来处理 - 请参阅下面的链接)。老实说,我不会在Spring工作,尽管我在这里和那里都涉足它。通常,我使用

@RequestMapping(..., produces = MediaType.APPLICATION_JSON_VALUE)

设置内容类型,但也许JSON是默认值。不要引用我,但是如果你得到JSON,而你还没有指定produces,那么它可能是默认值。 JSON不是唯一的格式。例如,上面的内容可以很容易地用XML发送,但是你需要producesMediaType.APPLICATION_XML_VALUE,我相信你需要为JAXB配置HttpMessageConverter。至于配置的JSON MappingJacksonHttpMessageConverter,当我们在类路径上有Jackson时。

我需要一些时间来了解Content Negotiation。它是REST的一个非常重要的部分。它将帮助您了解不同的响应格式以及如何将它们映射到您的方法。

答案 2 :(得分:4)

如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();
}

谢谢:)

答案 3 :(得分:1)

此外,返回类型由

确定
  1. HTTP请求所说的内容 - 在Accept标头中。尝试查看初始请求,看看接受设置的内容。

  2. HttpMessageConverters Spring设置了什么。如果杰克逊库在他的类路径上,Spring MVC将为XML(使用JAXB)和JSON设置转换器。

  3. 如果有选择,则选择一个 - 在本例中,它恰好是JSON。

    课程笔记中涵盖 。查找有关消息转换器和内容协商的说明。

答案 4 :(得分:1)

@RequestBody 注释将 HTTPRequest 主体绑定到域对象。 Spring 使用 HttpMessageConverters 自动将传入的 HTTP 请求反序列化为对象。 HttpMessageConverter 根据请求的内容类型转换请求正文以解析方法参数。 许多示例如何使用转换器 https://upcodein.com/search/jc/mg/ResponseBody/page/0