org.springframework.web.servlet.view.ContentNegotiatingViewResolver


restful服務中一個重要的特性就是一種資源可以有多種表現形式,在springmvc中可以使用ContentNegotiatingViewResolver這個視圖解析器來實現這種方式。

描述資源的三種形式

    一、使用擴展名

http://localhost:8080/test/user.xml   以xml格式呈現

http://localhost:8080/test/user.json  以json格式呈現

http://localhost:8080/test/user     以默認視圖呈現,如jsp

    二、使用http request header的Accept

 

GET /user HTTP/1.1

Accept:application/xml   請求時設置返回形式是xml,如使用ajax請求,則需要設置contentType:application/xml

 

GET /user HTTP/1.1

Accept:application/json  請求時設置返回形式是json,如使用ajax請求,則需要設置contentType:application/json

    三、使用參數

 

http://localhost:8080/test/user?format=json

http://localhost:8080/test/user?format=xml

 

上面了解了同一種資源的三種呈現方式,即json、xml、jsp,那么我們要如何使用ContentNegotiatingViewResolver類配置,使客戶端請求的方式不同,返回同一種資源的三種方式呢?

ContentNegotiatingViewResolver配置

ContentNegotiatingViewResolver是視圖解析器,我們在使用jsp這個視圖的時候也配置了一個視圖解析器InternalResourceViewResolver,他們都是視圖解析器,后者着重在配置一個默認的視圖解析即jsp;ContentNegotiatingViewResolver本身不會解析,他會分配其他的viewResolver去解析,並選擇一個看起來像是客戶端請求需要返回的一種 View 返回。

下面是ContentNegotiatingViewResolver的具體配置

復制代碼
<!--springmvc中根據后綴不同返回不同格式的配置 
        如,XXX.json  返回json格式
           XXX.xml   返回xml格式
           xxx       返回jsp
        -->
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <!--這里是解析器的執行順序,如果有多個的話,配置的數值越小,則越早執行--> <property name="order" value="1" /> <!-- 這里是是否啟用擴展名支持,默認就是true 例如 /user/{userid}.json --> <property name="favorPathExtension" value="true"></property> <!--這里是是否啟用參數支持,默認就是true 例如 /user/{userid}?format=json --> <property name="favorParameter" value="false"></property> <!--這里是否忽略掉accept header,默認就是false 例如 GET /user HTTP/1.1 Accept:application/json --> <property name="ignoreAcceptHeader" value="true"></property> <!-- 這里是擴展名到mimeType的映射, 例如 /user/{userid}.json 中的 .json 就會映射到 application/json --> <property name="mediaTypes"> <map> <entry key="json" value="application/json" /> <entry key="xml" value="application/xml" /> </map> </property> <!--視圖--> <property name="defaultViews"> <list> <!--json視圖--> <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"></bean> <!--xml視圖--> <bean class="org.springframework.web.servlet.view.xml.MarshallingView" <constructor-arg> <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <list> <value>com.cn.my.entity.Course</value> <value>com.cn.my.entity.CourseList</value> </list> </property> </bean> </constructor-arg> </bean> </list> </property> </bean>
復制代碼

order:如果存在多個viewResolver則order值小的被使用,如果沒有合適的viewResolver則會使用另外的;

favorPathExtension:是否支持擴展名,默認為true(支持),擴展名指的xxx.json、xxx.xml等形式

favorParameter:是否啟用參數支持,默認為true(支持),即xxx?format=json、xxx?format=xml等形式,這里的參數名默認為format,可以通過配置改變。

ignoreAcceptHeader:是否忽略accept header,默認是false(不忽略),即請求時指定的contentType:application/json等,由於我這里要使用擴展名的形式返回,所以把另外兩項都關閉了,可視不同情況,使用不同設置;

mediaTypes:配置擴展名到mimeType的映射,這里配置了json和xml的映射;

defaultViews:配置視圖,這里配置了json和xml的視圖,json使用的jackson;

最后,我還配置一個另外一個視圖解析器,InternalResourceViewResolver,

復制代碼
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="order" value="2" />
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    </bean>
復制代碼

這是jsp的視圖解析器,order屬性配置為了2,在無法匹配到json、xml的情況下,會返回jsp的視圖。

下面是controller的方法

復制代碼
package com.cn.my.controllor; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import com.cn.my.entity.Course; import com.cn.my.entity.CourseList; @Controller @RequestMapping("/mul") public class MultiView { @RequestMapping("/simple/{coursId}") public String method1(@PathVariable("coursId") String coursId,ModelMap model){ Course c=new Course(); c.setId(coursId); c.setContent("這是測試內容"); c.setName("李四"); model.put("course", c); return "course"; } }
復制代碼

這里使用的restful服務中的uri的格式,用到了@PathVariable注解,這里方法返回的String,且沒有@ResponseBody注解,在前邊的返回json一文中有返回json的配置,需要@ResponseBody注解,詳細的可以參看前邊,同時在方法參數中有ModelMap,為什么這里要返回一個字符串呢,目的是為了統一,我們知道如果要返回到jsp視圖,那么這里要返回的一個代表邏輯視圖名的字符串,為了使三種方式統一,這里返回的是字符串,如果不返回到jsp也可以返回一個實際的對象。

下面看測試結果,

請求:http://localhost:8081/springmvc/mul/simple2/1212.json

請求:http://localhost:8081/springmvc/mul/simple2/1212.xml

請求:http://localhost:8081/springmvc/mul/simple2/1212

最后一個jsp的視圖,本來是要在jsp頁面中輸出內容的,我這里沒做,只是輸出了一段話。請諒解!

 

從上邊的測試結果來看,我們分別使用了三種不同的請求方式去請求同一個資源,返回了各自的形式,這種方式很適合用在不同的系統調用同一個系統時,可能別的系統處理數據的方式不一樣,我們使用上邊的配置可以實現一套代碼,返回不同的形式。

最后

在配置默認的jsp解析器的時候也可以照下面的配置方式,

復制代碼
<!--springmvc中根據后綴不同返回不同格式的配置 
        如,XXX.json  返回json格式
           XXX.xml   返回xml格式
           xxx       返回jsp
        -->
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <!--這里是解析器的執行順序,如果有多個的話,配置的數值越小,則越早執行--> <property name="order" value="1" /> <!-- 這里是是否啟用擴展名支持,默認就是true 例如 /user/{userid}.json --> <property name="favorPathExtension" value="true"></property> <!--這里是是否啟用參數支持,默認就是true 例如 /user/{userid}?format=json --> <property name="favorParameter" value="false"></property> <!--這里是否忽略掉accept header,默認就是false 例如 GET /user HTTP/1.1 Accept:application/json --> <property name="ignoreAcceptHeader" value="true"></property> <!-- 這里是擴展名到mimeType的映射, 例如 /user/{userid}.json 中的 .json 就會映射到 application/json --> <property name="mediaTypes"> <map> <entry key="json" value="application/json" /> <entry key="xml" value="application/xml" /> </map> </property> <!--視圖解析器--> <property name="viewResolvers"> <list> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> </bean> </list> </property> <!--視圖--> <property name="defaultViews"> <list> <!--json視圖--> <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"></bean> <!--xml視圖--> <bean class="org.springframework.web.servlet.view.xml.MarshallingView" <constructor-arg> <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <list> <value>com.cn.my.entity.Course</value> <value>com.cn.my.entity.CourseList</value> </list> </property> </bean> </constructor-arg> </bean> </list> </property> </bean>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM