接上一篇對(duì)spring rest的描述.
一.REST內(nèi)容協(xié)商介紹
RESTful服務(wù)中很重要的一個(gè)特性即是同一資源,多種表述.也即如下面描述的三種方式:
1.使用http request header: Accept
GET /user/123 HTTP/1.1
Accept: application/xml //將返回xml格式數(shù)據(jù)

GET /user/123 HTTP/1.1
Accept: application/json //將返回json格式數(shù)據(jù)
2.使用擴(kuò)展名
/user/123.xml 將返回xml格式數(shù)據(jù)
/user/123.json 將返回json格式數(shù)據(jù)
/user/123.html 將返回html格式數(shù)據(jù)
3.使用參數(shù)
/user/123?format=xml //將返回xml數(shù)據(jù)
/user/123?format=json //將返回json數(shù)據(jù)
而以上三種各有優(yōu)缺點(diǎn):
1.使用Accept header:
這一種為教科書中通常描述的一種,理想中這種方式也是最好的,但如果你的資源要給用戶直接通過瀏覽器訪問(即html展現(xiàn)),那么由于瀏覽器的差異,發(fā)送上來的Accept Header頭將是不一樣的. 將導(dǎo)致服務(wù)器不知要返回什么格式的數(shù)據(jù)給你. 下面是瀏覽器的Accept Header
chrome:
Accept:application/xml,application/xhtml+xml,textml;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
firefox:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
IE8:
Accept:image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
2.使用擴(kuò)展名
喪失了同一url多種展現(xiàn)的方式,但現(xiàn)在這種在實(shí)際環(huán)境中是使用最多的.因?yàn)楦臃铣绦騿T的審美觀.
3.使用參數(shù)
可能由于要編寫的字符較多,所以較少使用.
帶著上面的選擇: 使用擴(kuò)展名,我們來看一下spring中如何配置這部分.
二.spring rest配置
現(xiàn)spring完成內(nèi)容協(xié)商(content negotiation)的工作是由ContentNegotiatingViewResolver來完成的.它的工作模式支持我上面講的三種,
ContentNegotiatingViewResolver是根據(jù)客戶提交的MimeType(如 text/html,application/xml)來跟服務(wù)端的一組viewResover的MimeType相比較,如果符合,即返回viewResover的數(shù)據(jù).
而 /user/123.xml, ContentNegotiatingViewResolver會(huì)首先將 .xml 根據(jù)mediaTypes屬性將其轉(zhuǎn)換成 application/xml,然后完成前面所說的比較.
下面是ContentNegotiatingViewResolver的完全配置.
<!-- 根據(jù)客戶端的不同的請(qǐng)求決定不同的view進(jìn)行響應(yīng), 如 /blog/1.json /blog/1.xml -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<!-- 設(shè)置為true以忽略對(duì)Accept Header的支持-->
<property name="ignoreAcceptHeader" value="true"/>
<!-- 在沒有擴(kuò)展名時(shí)即: "/user/1" 時(shí)的默認(rèn)展現(xiàn)形式 -->
<property name="defaultContentType" value="text/html"/>
<!-- 擴(kuò)展名至mimeType的映射,即 /user.json => application/json -->
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
<!-- 用于開啟 /userinfo/123?format=json 的支持 -->
<property name="favorParameter" value="false"/>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/pages"/>
<property name="suffix" value=".jsp"></property>
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<!-- for application/json -->
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<!-- for application/xml -->
<!--
<bean class="org.springframework.web.servlet.view.xml.MarshallingView" >
<property name="marshaller">
<bean class="org.springframework.oxm.xstream.XStreamMarshaller"/>
</property>
</bean>
-->
</list>
</property>
</bean>
查看demo:
http://demo.rapid-framework.org.cn:8080/springmvc_rest_demo/userinfo
demo下載:
http://rapid-framework.googlecode.com/files/springmvc_rest_demo.zip