首页 文章

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

提问于
浏览
71

我有一个方法,通过以下方式注释:

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

此方法处理对URL /orders 表示的资源发出的HTTP请求 GET .

此方法调用返回 List 的DAO对象 .

其中 Account 代表系统上的用户,并且有一些代表此用户的字段,如:

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

    ...............................
    ...............................
    ...............................
}

我的问题是: How exactly the does the @ResponseBody annotation work?

它位于返回的 List<Account> 对象之前,因此我认为它引用了此List . 课程文档指出此注释用于以下功能:

确保HTTP消息转换器(而不是MVC视图)将结果写入HTTP响应 .

并阅读官方Spring文档:http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html

它似乎需要 List<Account> 对象并将其放入 Http Response . 这是正确的还是我的误解?

写入前一个 accountSummary() 方法的注释中有:

访问http:// localhost:8080 / rest-ws / app / accounts时应该获得JSON结果

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

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

4 回答

  • 1

    首先要理解的是架构的不同之处 .

    一端你有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 时,我们说我们不希望产生一个视图 . 我们只想以我们指定的格式发送返回对象作为正文 . 虽然我在这里和那里涉猎它,但我们不会对Spring有太多的帮助 . 通常,我使用

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

    设置内容类型,但也许JSON是默认值 . Don 't quote me, but if you are getting JSON, and you haven' t指定了 produces ,然后可能是默认值 . JSON不是唯一的格式 . 例如,上面的内容很容易用XML发送,但你需要 producesMediaType.APPLICATION_XML_VALUE ,我相信你需要为JAXB配置 HttpMessageConverter . 至于配置的JSON MappingJacksonHttpMessageConverter ,当我们在类路径上有Jackson时 .

    我需要一些时间来了解Content Negotiation . 它's a very important part of REST. It'将帮助您了解不同的响应格式以及如何将它们映射到您的方法 .

  • 48

    此外,返回类型由确定

    • HTTP请求所说的内容 - 在Accept标头中 . 尝试查看初始请求,看看Accept设置了什么 .

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

    如果有选择它会选择一个 - 在这个例子中,它恰好是JSON .

    课程说明中对此进行了介绍 . 查找有关消息转换器和内容协商的说明 .

  • 125

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

    谢谢 :)

  • 4

    首先,注释没有注释 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 .

相关问题