Spring 3.x MVC 入門4 -- @ResponseBody & @RequestBody &HttpMessageConverter

本文摘自:http://www.cnblogs.com/zhaoyang/archive/2012/01/07/2315436.html

@ResponseBody & @RequestBody

作用?

@RequestBody 將 HTTP 請求正文插入方法中,使用適合的HttpMessageConverter將請求體寫入某個對象。

 

@ResponseBody 將內容或對象作爲 HTTP 響應正文返回,使用@ResponseBody將會跳過視圖處理部分,而是調用適合HttpMessageConverter,將返回值寫入輸出流。

 

HttpMessageConverter接口

<mvc:annotation-driven  />開啓了之後它給AnnotationMethodHandlerAdapter初始化7個轉換器,可以通過調用AnnotationMethodHandlerAdapter類的getMessageConverts()方法來獲取轉換器的一個集合 List<HttpMessageConverter>

 

默認給AnnotationMethodHandlerAdapter初始化的有(當然我們也可以添加自定義的converter)

 

ByteArrayHttpMessageConverter

StringHttpMessageConverter

ResourceHttpMessageConverter

SourceHttpMessageConverter<T>

XmlAwareFormHttpMessageConverter

Jaxb2RootElementHttpMessageConverter

MappingJacksonHttpMessageConverter

 

Spring是如何尋找最佳的HttpMessageConverter

1 首先獲取註冊的所有HttpMessageConverter集合

 

2 然後客戶端的請求header中尋找客戶端可接收的類型,

比如  Accept application/json,application/xml等,組成一個集合

 

3 所有的HttpMessageConverter 都有canRead和canWrite方法 返回值都是boolean,看這個HttpMessageConverter是否支持當前請求的讀與寫,讀對應@RequestBody註解, 寫對應@ResponseBody註解

 

4 遍歷HttpMessageConverter集合與前面獲取可接受類型進行匹配,如果匹配直接使用當前第一個匹配的HttpMessageConverter,然後return(一般是通過Accept和返回值對象的類型進行匹配)

 

例如

StringHttpMessageConverter           

支持String , Accept所有類型

 

MappingJacksonHttpMessageConverter  

支持Map List 實體對象等等  ,Accept:application/json

 

 

示例:

目標:

使用ResponseBody根據head的Accept不同對同一地址請求分別來呈現一個實體的json與xml結果

 

由於<context:annotation-config />

默認會初始化AnnotationMethodHanlderAdapter,但我們返回xml內容需要對這個HandlerAdapter進行一定的修改,所以配置文件如下:

 

<context:component-scan base-package="com.controls" />

   

<context:annotation-config />

   

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">

        <property name="messageConverters">

            <list>

                <ref bean="stringHttpMessageConverter" />

                <ref bean="jsonHttpMessageConverter" />

                <ref bean="marshallingHttpMessageConverter" />

            </list>

        </property>

    </bean>

 

<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter" /> 

 

<bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />

 

<bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">

        <constructor-arg ref="jaxbMarshaller" />

        <property name="supportedMediaTypes" value="application/xml"></property>

</bean>

   

<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">

        <property name="classesToBeBound">

            <list>

                <value>com.model.User</value>

            </list>

        </property>

</bean>

 

注:要使用Jaxb2Marshaller我們在對應的實體,比如User類上需要標明

 

@XmlRootElement 註解,需要引入

 

import javax.xml.bind.annotation.XmlRootElement;

這個包。

 

 

Controller中應對請求的方法

 

@RequestMapping(value="/user/{userid}", method=RequestMethod.GET)

public @ResponseBody User queryUser(@PathVariable("userid") long userID) {

       Calendar d = Calendar.getInstance();

       d.set(1987, 12, 9);

       User u = new User();

       u.setUserID(userID);

       u.setUserName("zhaoyang");

       u.setBirth(d.getTime());

       return u;

}

 

接着我們使用curl這個工具進行測試

如下圖:

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章