badqiu

          XPer
          隨筆 - 46, 文章 - 3, 評(píng)論 - 195, 引用 - 0
          數(shù)據(jù)加載中……

          spring REST中的內(nèi)容協(xié)商(同一資源,多種展現(xiàn):xml,json,html)

          接上一篇對(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

          posted on 2009-12-21 14:36 badqiu 閱讀(7620) 評(píng)論(2)  編輯  收藏

          評(píng)論

          # re: spring REST中的內(nèi)容協(xié)商(同一資源,多種展現(xiàn):xml,json,html)  回復(fù)  更多評(píng)論   

          看起來樓主是下過苦功夫的啊。呵呵

          # re: spring REST中的內(nèi)容協(xié)商(同一資源,多種展現(xiàn):xml,json,html)  回復(fù)  更多評(píng)論   


          不錯(cuò),正是我要尋找的..

          2011-03-21 12:43 | HideHai

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 泰顺县| 开封市| 汨罗市| 新田县| 响水县| 余姚市| 永兴县| 晋江市| 翁牛特旗| 大洼县| 平利县| 六盘水市| 大渡口区| 哈尔滨市| 松原市| 肃南| 漯河市| 宁波市| 龙州县| 方正县| 榆中县| 卓资县| 叙永县| 静乐县| 竹溪县| 芦山县| 桃园县| 饶阳县| 宿松县| 宁陵县| 玉林市| 罗定市| 湖南省| 娱乐| 柯坪县| 玉门市| 墨竹工卡县| 杭锦旗| 辛集市| 巧家县| 庆元县|