@responsebody和responseentity的理解
简单来说就是这样:@responsebody有没有这个区别我举个例子更清楚一点,如果有@responsebody这个注解,return “/ssyer/index”,返回数据就是字符/ssyer/index,没有经过视图处理器直接返回了,如果没有这个注解,那么返回的就是/ssyer/index这个地址所指的内容,也就是经过经过视图处理器处理后的视图,返回的是视图。
responseentity因为是经过视图解析器的,所以它的contenttype和charset是在视图解析器的配置中设置的
那么,加了@responsebody的返回呢,
Responseentity,这个的作用就是将tostring的字符数据转化为json的数据格式,我认为这是它的最大作用。
@responsebody表示该方法的返回结果直接写入HTTP response body中
一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。
Spring3 MVC的@ResponseBody 的作用是把返回值直接写到HTTP response body里。
Spring MVC 中的 REST 支持
@Controller
使用 @Controller 注释对将成为 MVC 中控制器的类进行注释并处理 HTTP 请求。
@RequestMapping
使用 @RequestMapping 注释对函数进行注释,该函数处理某些 HTTP 方法、URI 或 HTTP 头。此注释是 Spring REST 支持的关键。可以更改 method 参数以处理其他 HTTP 方法。
HttpMessageConverter
HTTP 请求和响应是基于文本的,意味着浏览器和服务器通过交换原始文本进行通信。但是,使用 Spring,controller 类中的方法返回纯 ‘String’ 类型和域模型(或其他 Java 内建对象)。如何将对象序列化/反序列化为原始文本?这由HttpMessageConverter 处理。
Http请求和响应报文本质上都是一串字符串,当请求报文来到java世界,它会被封装成为一个ServletInputStream的输入流,供我们读取报文。响应报文则是通过一个ServletOutputStream的输出流,来输出响应报文。
我们从流中,只能读取到原始的字符串报文,同样,我们往输出流中,也只能写原始的字符。而在java世界中,处理业务逻辑,都是以一个个有业务意义的对象为处理维度的,那么在报文到达SpringMVC和从SpringMVC出去,都存在一个字符串到java对象的阻抗问题。这一过程,不可能由开发者手工转换。我们知道,在Struts2中,采用了OGNL来应对这个问题,而在SpringMVC中,它是HttpMessageConverter机制。我们先来看两个接口。
对消息转换器最高层次的接口抽象,描述了一个消息转换器的一般特征,我们可以从这个接口中定义的方法,来领悟Spring3.x的设计者对这一机制的思考过程。
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, MediaType mediaType);
boolean canWrite(Class<?> clazz, MediaType mediaType);
List<MediaType> getSupportedMediaTypes();
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
HttpMessageConverter接口的定义出现了成对的canRead(),read()和canWrite(),write()方法,MediaType是对请求的Media Type属性的封装。举个例子,当我们声明了下面这个处理方法。
@RequestMapping(value="/string", method=RequestMethod.POST)
public @ResponseBody String readString(@RequestBody String string) {
return "Read string '" + string + "'";
}
- 1
- 2
- 3
- 4
在SpringMVC进入readString方法前,会根据@RequestBody注解选择适当的HttpMessageConverter实现类来将请求参数解析到string变量中,具体来说是使用了StringHttpMessageConverter类,它的canRead()方法返回true,然后它的read()方法会从请求中读出请求参数,绑定到readString()方法的string变量中。
当SpringMVC执行readString方法后,由于返回值标识了@ResponseBody,SpringMVC将使用StringHttpMessageConverter的write()方法,将结果作为String值写入响应报文,当然,此时canWrite()方法返回true。
我们可以用下面的图,简单描述一下这个过程。
在我们对SpringMVC源码分析的过程中,我们可以从HttpMessageConverter机制中领悟到类似的道理。在SpringMVC的设计者眼中,一次请求报文和一次响应报文,分别被抽象为一个请求消息HttpInputMessage和一个响应消息HttpOutputMessage。
处理请求时,由合适的消息转换器将请求报文绑定为方法中的形参对象,在这里,同一个对象就有可能出现多种不同的消息形式,比如json和xml。同样,当响应请求时,方法的返回值也同样可能被返回为不同的消息形式,比如json和xml。
在SpringMVC中,针对不同的消息形式,我们有不同的HttpMessageConverter实现类来处理各种消息形式。但是,只要这些消息所蕴含的“有效信息”是一致的,那么各种不同的消息转换器,都会生成同样的转换结果。至于各种消息间解析细节的不同,就被屏蔽在不同的HttpMessageConverter实现类中了。
表 1. HttpMessageConverter 示例:
配置 HttpMessageConverter。要生成多个具象,自定义几个 HttpMessageConverter 实例,以将对象转换为不同的媒体类型。此部分包括 JSON、ATOM 和 XML 媒体类型。
JSON
从最简单的示例开始。JSON 是一个轻量型的数据交换格式,人们可轻松地进行读取和编写。清单 1 显示了配置 JSON converter 的代码。
清单 1. 配置 rest-servlet.xml 中的 HttpMessageConverter
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
<ref bean="marshallingConverter" />
<ref bean="atomConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
MappingJacksonHttpMessageConverter 用于将对象转换为 JSON,反之亦然。此内置转换程序使用 Jackson 的 ObjectMapper 将 JSON 映射到 JavaBean,因此您必须将下列 Jackson JAR 文件添加到类路径。
org.codehaus.jackson.jar
org.codehaus.jackson.mapper.jar
下一步是编写一个方法,处理请求 JSON 具象的请求。清单 2 显示了详细信息
清单 2. 处理在 EmployeeController 中定义的 JSON 请求
@RequestMapping(method=RequestMethod.GET, value="/emp/{id}", headers="Accept=application/json")
public @ResponseBody Employee getEmp(@PathVariable String id) {
Employee e = employeeDS.get(Long.parseLong(id));
return e;
}
@RequestMapping(method=RequestMethod.GET, value="/emps", headers="Accept=application/json")
public @ResponseBody EmployeeListinggetAllEmp() {
List<Employee> employees = employeeDS.getAll();
EmployeeListinglist = new EmployeeList(employees);
return list;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
@ResponseBody 注释用于将返回对象(Employee 或 EmployeeList)变为响应的正文内容,将使用 MappingJacksonHttpMessageConverter 将其映射到 JSON。
使用 HttpMessageConverter 和 @ResponseBody,您可以实现多个具象,而无需包含 Spring 的视图技术 — 这是使用 ContentNegotiatingViewResolver 所不具有的一个优势。
Spring3 MVC的@ResponseBody 的作用是把返回值直接写到HTTP response body里。 使用AnnotationMethodHandlerAdapter的handleResponseBody方法, AnnotationMethodHandlerAdapter使用request header中”Accept”的值和messageConverter支持的MediaType进行匹配,然后会用”Accept”的第一个值写入 response的”Content-Type”。重点是根据accept和返回的内容进行匹配。
AnnotationMethodHandlerAdapter使用request header中”Accept”的值和messageConverter支持的MediaType进行匹配
AnnotationMethodHandlerAdapter使用request
header中”Accept”的值和messageConverter支持的MediaType进行匹配
AnnotationMethodHandlerAdapter使用request
header中”Accept”的值和messageConverter支持的MediaType进行匹配
AnnotationMethodHandlerAdapter将会初始化7个转换器,可以通过调用AnnotationMethodHandlerAdapter的getMessageConverts()方法来获取转换器的一个集合
上一篇: 解决maven找不到jar包的问题
推荐阅读
-
Android深入理解Context(二)Activity和Service的Context创建过程
-
Python中strip() 函数和 split() 函数的理解
-
深入理解数据库索引采用B树和B+树的原因
-
深入理解JVM(三) -- 对象的内存布局和访问定位
-
深入理解ob_flush和flush的区别
-
个人对Pandas中agg、apply和transform函数的理解
-
深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)_PHP
-
laravel中的Facades和Ioc Container怎么理解?
-
php操作mysql_fetch_row和mysql_fetch_assoc 的一行不理解哎
-
模板的特化和偏特化以及相关理解