@responsebody和responseentity的理解

来源:互联网 发布:农村淘宝村小二招募 编辑:程序博客网 时间:2024/05/29 18:17

简单来说就是这样:@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()方法来获取转换器的一个集合


阅读全文
0 0
原创粉丝点击