Java Spring @ResponseBody 注释是如何工作的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28646332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does the Spring @ResponseBody annotation work?
提问by AndreaNobili
I have a method that is annotated in the following way:
我有一个按以下方式注释的方法:
/**
* 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();
}
So I know that by this annotation:
所以我知道通过这个注释:
@RequestMapping(value="/orders", method=RequestMethod.GET)
this method handle GETHTTP requests made to the resource represented by the URL /orders.
此方法处理对 URL /orders表示的资源发出的GETHTTP 请求。
This method calls a DAO object that returns a List.
此方法调用返回List的 DAO 对象。
where Accountrepresents a user on the system and has some fields that represent this user, something like:
其中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>();
...............................
...............................
...............................
}
My question is: How exactly the does the @ResponseBody
annotation work?
我的问题是:注释究竟是如何@ResponseBody
工作的?
It is situated before the returned List<Account>
object so I think that it refers to this List. The course documentation states that this annotation serves the function to:
它位于返回的List<Account>
对象之前,所以我认为它指的是这个 List。课程文档指出,此注释的作用是:
ensure that the result will be written to the HTTP response by an HTTP Message Converter (instead of an MVC View).
确保结果将由 HTTP 消息转换器(而不是 MVC 视图)写入 HTTP 响应。
And also reading on the official Spring documentation: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html
并阅读官方 Spring 文档:http: //docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html
it seems that it takes the List<Account>
object and puts it into the Http Response
. Is this correct or am I misunderstanding?
似乎它需要List<Account>
对象并将其放入Http Response
. 这是正确的还是我误解了?
Written into the comment of the previous accountSummary()
method there is:
写在前面accountSummary()
方法的注释中有:
You should get JSON results when accessing http://localhost:8080/rest-ws/app/accounts
访问http://localhost:8080/rest-ws/app/accounts时应该得到 JSON 结果
So what exactly does this mean? Does it mean that the List<Account>
object returned by the accountSummary()
method is automatically converted into JSON
format and then put into the Http Response
? Or what?
那么这到底是什么意思呢?是不是说方法List<Account>
返回的对象accountSummary()
会自动转换成JSON
format然后放入Http Response
?或者是什么?
If this assertion is true, where is it specified that the object will be automatically converted into JSON
format? Is the standard format adopted when the @ResponseBody
annotation is used or is it specified elsewhere?
如果这个断言为真,那么在哪里指定对象将自动转换为JSON
格式?@ResponseBody
使用注解时采用的是标准格式还是别处规定的?
采纳答案by JB Nizet
First of all, the annotation doesn't annotate List
. It annotates the method, just as RequestMapping
does. Your code is equivalent to
首先,注释没有 annotate List
。它对方法进行注释,就像那样RequestMapping
。你的代码相当于
@RequestMapping(value="/orders", method=RequestMethod.GET)
@ResponseBody
public List<Account> accountSummary() {
return accountManager.getAllAccounts();
}
Now what the annotation means is that the returned value of the method will constitute the body of the HTTP response. Of course, an HTTP response can't contain Java objects. So this list of accounts is transformed to a format suitable for REST applications, typically JSON or XML.
现在注解的意思是方法的返回值将构成 HTTP 响应的主体。当然,HTTP 响应不能包含 Java 对象。因此,此帐户列表被转换为适合 REST 应用程序的格式,通常是 JSON 或 XML。
The choice of the format depends on the installed message converters, on the values of the produces
attributeof the RequestMapping annotation, and on the content type that the client accepts (that is available in the HTTP request headers). For example, if the request says it accepts XML, but not JSON, and there is a message converter installed that can transform the list to XML, then XML will be returned.
格式的选择取决于安装的消息转换器、RequestMapping 注释的produces
属性值以及客户端接受的内容类型(在 HTTP 请求标头中可用)。例如,如果请求说它接受 XML,但不接受 JSON,并且安装了可以将列表转换为 XML 的消息转换器,则将返回 XML。
回答by Paul Samsotha
The first basic thing to understand is the difference in architectures.
首先要理解的基本内容是架构的差异。
One end you have the MVC architecture, which is based on your normal web app, using web pages, and the browser makes a request for a page:
一方面你有 MVC 架构,它基于你的普通 web 应用程序,使用网页,浏览器请求一个页面:
Browser <---> Controller <---> Model
| |
+-View-+
The browser makes a request, the controller (@Controller) gets the model (@Entity), and creates the view (JSP) from the model and the view is returned back to the client. This is the basic web app architecture.
浏览器发出请求,控制器(@Controller)获取模型(@Entity),并从模型创建视图(JSP)并将视图返回给客户端。这是基本的 Web 应用程序架构。
On the other end, you have a RESTful architecture. In this case, there is no View. The Controller only sends back the model (or resource representation, in more RESTful terms). The client can be a JavaScript application, a Java server application, any application in which we expose our REST API to. With this architecture, the client decides what to do with this model. Take for instance Twitter. Twitter as the Web (REST) API, that allows our applications to use its API to get such things as status updates, so that we can use it to put that data in our application. That data will come in some format like JSON.
另一方面,您有一个 RESTful 架构。在这种情况下,没有视图。控制器只发回模型(或资源表示,在更多 RESTful 术语中)。客户端可以是 JavaScript 应用程序、Java 服务器应用程序、我们向其中公开 REST API 的任何应用程序。使用此架构,客户端决定如何使用此模型。以推特为例。Twitter 作为 Web (REST) API,它允许我们的应用程序使用它的 API 来获取诸如状态更新之类的东西,以便我们可以使用它来将这些数据放入我们的应用程序中。该数据将以某种格式出现,例如 JSON。
That being said, when working with Spring MVC, it was first built to handle the basic web application architecture. There are may different method signature flavors that allow a view to be produced from our methods. The method could return a ModelAndView
where we explicitly create it, or there are implicit ways where we can return some arbitrary object that gets set into model attributes. But either way, somewhere along the request-response cycle, there will be a view produced.
话虽如此,在使用 Spring MVC 时,它首先是为了处理基本的 Web 应用程序架构而构建的。可能有不同的方法签名风格允许从我们的方法中生成视图。该方法可以返回一个ModelAndView
我们显式创建它的地方,或者我们可以通过隐式方式返回一些设置为模型属性的任意对象。但无论哪种方式,在请求-响应周期的某个地方,都会产生一个视图。
But when we use @ResponseBody
, we are saying that we do not want a view produced. We just want to send the return object as the body, in whatever format we specify. We wouldn't want it to be a serialized Java object (though possible). So yes, it needs to be converted to some other common type (this type is normally dealt with through content negotiation - see link below). Honestly, I don't work much with Spring, though I dabble with it here and there. Normally, I use
但是当我们使用 时@ResponseBody
,我们是说我们不希望产生一个视图。我们只想以我们指定的任何格式发送返回对象作为正文。我们不希望它是一个序列化的 Java 对象(尽管可能)。所以是的,它需要转换为其他一些常见类型(这种类型通常通过内容协商处理 - 请参见下面的链接)。老实说,我对 Spring 的工作不多,尽管我到处涉足它。通常,我使用
@RequestMapping(..., produces = MediaType.APPLICATION_JSON_VALUE)
to set the content type, but maybe JSON is the default. Don't quote me, but if you are getting JSON, and you haven't specified the produces
, then maybe it is the default. JSON is not the only format. For instance, the above could easily be sent in XML, but you would need to have the produces
to MediaType.APPLICATION_XML_VALUE
and I believe you need to configure the HttpMessageConverter
for JAXB. As for the JSON MappingHymansonHttpMessageConverter
configured, when we have Hymanson on the classpath.
设置内容类型,但 JSON 可能是默认值。不要引用我的话,但是如果您正在获取 JSON,并且您还没有指定produces
,那么它可能是默认值。JSON 不是唯一的格式。例如,上面的内容可以很容易地以 XML 格式发送,但是您需要拥有produces
toMediaType.APPLICATION_XML_VALUE
并且我相信您需要HttpMessageConverter
为 JAXB配置。至于MappingHymansonHttpMessageConverter
配置的 JSON ,当我们在类路径上有 Hymanson 时。
I would take some time to learn about Content Negotiation. It's a very important part of REST. It'll help you learn about the different response formats and how to map them to your methods.
我会花一些时间来了解内容协商。它是 REST 的一个非常重要的部分。它将帮助您了解不同的响应格式以及如何将它们映射到您的方法。
回答by paulchapman
Further to this, the return type is determined by
除此之外,返回类型由
What the HTTP Request says it wants - in its Accept header. Try looking at the initial request as see what Accept is set to.
What HttpMessageConverters Spring sets up. Spring MVC will setup converters for XML (using JAXB) and JSON if Hymanson libraries are on he classpath.
HTTP 请求说它想要什么 - 在它的 Accept 标头中。尝试查看初始请求,看看 Accept 设置为什么。
什么 HttpMessageConverters Spring 设置。如果 Hymanson 库在类路径上,Spring MVC 将为 XML(使用 JAXB)和 JSON 设置转换器。
If there is a choice it picks one - in this example, it happens to be JSON.
如果有选择,它会选择一个 - 在这个例子中,它恰好是 JSON。
This iscovered in the course notes. Look for the notes on Message Convertors and Content Negotiation.
这是覆盖在课程笔记。查找有关消息转换器和内容协商的说明。