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

GET /user/123 HTTP/1.1
Accept: application/json //將返回json格式數據
2.使用擴展名
/user/123.xml 將返回xml格式數據
/user/123.json 將返回json格式數據
/user/123.html 將返回html格式數據
3.使用參數
/user/123?format=xml //將返回xml數據
/user/123?format=json //將返回json數據
而以上三種各有優缺點:
1.使用Accept header:
這一種為教科書中通常描述的一種,理想中這種方式也是最好的,但如果你的資源要給用戶直接通過瀏覽器訪問(即html展現),那么由于瀏覽器的差異,發送上來的Accept Header頭將是不一樣的. 將導致服務器不知要返回什么格式的數據給你. 下面是瀏覽器的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.使用擴展名
喪失了同一url多種展現的方式,但現在這種在實際環境中是使用最多的.因為更加符合程序員的審美觀.
3.使用參數
可能由于要編寫的字符較多,所以較少使用.
帶著上面的選擇: 使用擴展名,我們來看一下spring中如何配置這部分.
二.spring rest配置
現spring完成內容協商(content negotiation)的工作是由ContentNegotiatingViewResolver來完成的.它的工作模式支持我上面講的三種,
ContentNegotiatingViewResolver是根據客戶提交的MimeType(如 text/html,application/xml)來跟服務端的一組viewResover的MimeType相比較,如果符合,即返回viewResover的數據.
而 /user/123.xml, ContentNegotiatingViewResolver會首先將 .xml 根據mediaTypes屬性將其轉換成 application/xml,然后完成前面所說的比較.
下面是ContentNegotiatingViewResolver的完全配置.
<!-- 根據客戶端的不同的請求決定不同的view進行響應, 如 /blog/1.json /blog/1.xml -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<!-- 設置為true以忽略對Accept Header的支持-->
<property name="ignoreAcceptHeader" value="true"/>
<!-- 在沒有擴展名時即: "/user/1" 時的默認展現形式 -->
<property name="defaultContentType" value="text/html"/>
<!-- 擴展名至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