@responsebody和responseentity的理解

  • Post author:
  • Post category:其他


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



版权声明:本文为qq_39385706原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。