SpringMvc知識 (2)

SpringMVC視圖解析器
首先我們先回顧一下SpringMVC的大概工作流程
(1) 當我們對SpringMVC控制的資源發起請求時,這些請求都會被SpringMVC的DispatcherServlet攔截處理。
(2) 接着Spring會藉助HandlerMapping根據url映射定位到相應的controller。
(3) 用戶請求的數據經過業務處理層處理之後返回一個ModelAndView對象。
(4) 在獲得了ModelAndView對象之後Spring就需要把該View渲染給用戶,即返回給瀏覽器。

在這個渲染的過程中,發揮作用的就是ViewResolverView。當Handler返回的ModelAndView中不包含真正的視圖,只返回一個邏輯視圖名稱的時候,ViewResolver就會把該邏輯視圖名稱解析爲真正的視圖View對象。View是真正進行視圖渲染,把結果返回給瀏覽器的。

ViewResolver和View介紹

  • ViewResolver只是把邏輯視圖名稱解析爲對象的View對象。View接口的主要作用是用於處理視圖,然後返回給客戶端。
    Spring爲我們提供了非常多的試圖解析器,下面列舉幾個:

    AbstractCachingViewResolver:這是一個抽象類,這種視圖解析器會把它曾經解析過的視圖保存起來,然後每次要解析視圖的時候先從緩存裏面找,如果找到了對應的視圖就直接返回,如果沒有就創建一個新的視圖對象,然後把它放到一個用於緩存的map中,接着再把新建的視圖返回。使用這種視圖緩存的方式可以把解析視圖的性能問題降到最低。
    UrlBasedViewResolver:它是對ViewResolver的一種簡單實現,而且繼承了AbstractCachingViewResolver,主要就是提供的一種拼接URL的方式來解析視圖,它可以讓我們通過prefix屬性指定一個指定的前綴,通過suffix屬性指定一個指定的後綴,然後把返回的邏輯視圖名稱加上指定的前綴和後綴就是指定的視圖URL了。如prefix=/WEB-INF/jsps/,suffix=.jsp,返回的視圖名稱viewName=test/indx,則UrlBasedViewResolver解析出來的視圖URL就是/WEB-INF/jsps/test/index.jsp。默認的prefix和suffix都是空串。URLBasedViewResolver支持返回的視圖名稱中包含redirect:前綴,這樣就可以支持URL在客戶端的跳轉,如當返回的視圖名稱是”redirect:test.do”的時候,URLBasedViewResolver發現返回的視圖名稱包含”redirect:”前綴,於是把返回的視圖名稱前綴”redirect:”去掉,取後面的test.do組成一個RedirectView,RedirectView中將把請求返回的模型屬性組合成查詢參數的形式組合到redirect的URL後面,然後調用HttpServletResponse對象的sendRedirect方法進行重定向。同樣URLBasedViewResolver還支持forword:前綴,對於視圖名稱中包含forword:前綴的視圖名稱將會被封裝成一個InternalResourceView對象,然後在服務器端利用RequestDispatcher的forword方式跳轉到指定的地址。使用UrlBasedViewResolver的時候必須指定屬性viewClass,表示解析成哪種視圖,一般使用較多的就是InternalResourceView,利用它來展現jsp,但是當我們使用JSTL的時候我們必須使用JstlView。下面是一段UrlBasedViewResolver的定義,根據該定義,當返回的邏輯視圖名稱是test的時候,UrlBasedViewResolver將把邏輯視圖名稱加上定義好的前綴和後綴,即“/WEB-INF/test.jsp”,然後新建一個viewClass屬性指定的視圖類型予以返回,即返回一個url爲“/WEB-INF/test.jsp”的InternalResourceView對象。
    Xml代碼

<bean  
   class="org.springframework.web.servlet.view.UrlBasedViewResolver">  
   <property name="prefix" value="/WEB-INF/" />  
   <property name="suffix" value=".jsp" />  
   <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>  
</bean> 

InternalResourceViewResolver:它是URLBasedViewResolver的子類,所以URLBasedViewResolver支持的特性它都支持。在實際應用中InternalResourceViewResolver也是使用的最廣泛的一個視圖解析器。那麼InternalResourceViewResolver有什麼自己獨有的特性呢?單從字面意思來看,我們可以把InternalResourceViewResolver解釋爲內部資源視圖解析器,這就是InternalResourceViewResolver的一個特性。InternalResourceViewResolver會把返回的視圖名稱都解析爲InternalResourceView對象,InternalResourceView會把Controller處理器方法返回的模型屬性都存放到對應的request屬性中,然後通過RequestDispatcher在服務器端把請求forword重定向到目標URL。比如在InternalResourceViewResolver中定義了prefix=/WEB-INF/,suffix=.jsp,然後請求的Controller處理器方法返回的視圖名稱爲test,那麼這個時候InternalResourceViewResolver就會把test解析爲一個InternalResourceView對象,先把返回的模型屬性都存放到對應的HttpServletRequest屬性中,然後利用RequestDispatcher在服務器端把請求forword到/WEB-INF/test.jsp。這就是InternalResourceViewResolver一個非常重要的特性,我們都知道存放在/WEB-INF/下面的內容是不能直接通過request請求的方式請求到的,爲了安全性考慮,我們通常會把jsp文件放在WEB-INF目錄下,而InternalResourceView在服務器端跳轉的方式可以很好的解決這個問題。下面是一個InternalResourceViewResolver的定義,根據該定義當返回的邏輯視圖名稱是test的時候,InternalResourceViewResolver會給它加上定義好的前綴和後綴,組成“/WEB-INF/test.jsp”的形式,然後把它當做一個InternalResourceView的url新建一個InternalResourceView對象返回。
Xml代碼

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
   <property name="prefix" value="/WEB-INF/"/>  
   <property name="suffix" value=".jsp"></property>  
</bean>  

視圖解析鏈

   在SpringMVC中可以同時定義多個ViewResolver視圖解析器,然後它們會組成一個ViewResolver鏈。當Controller處理器方法返回一個邏輯視圖名稱後,ViewResolver鏈將根據其中ViewResolver的優先級來進行處理。所有的ViewResolver都實現了Ordered接口,在Spring中實現了這個接口的類都是可以排序的。在ViewResolver中是通過order屬性來指定順序的,默認都是最大值。所以我們可以通過指定ViewResolver的order屬性來實現ViewResolver的優先級,order屬性是Integer類型,order越小,對應的ViewResolver將有越高的解析視圖的權利,所以第一個進行解析的將是ViewResolver鏈中order值最小的那個。當一個ViewResolver在進行視圖解析後返回的View對象是null的話就表示該ViewResolver不能解析該視圖,這個時候如果還存在其他order值比它大的ViewResolver就會調用剩餘的ViewResolver中的order值最小的那個來解析該視圖,依此類推。當ViewResolver在進行視圖解析後返回的是一個非空的View對象的時候,就表示該ViewResolver能夠解析該視圖,那麼視圖解析這一步就完成了,後續的ViewResolver將不會再用來解析該視圖。當定義的所有ViewResolver都不能解析該視圖的時候,Spring就會拋出一個異常。
   基於Spring支持的這種ViewResolver鏈模式,我們就可以在SpringMVC應用中同時定義多個ViewResolver,給定不同的order值,這樣我們就可以對特定的視圖特定處理,以此來支持同一應用中有多種視圖類型。注意:像InternalResourceViewResolver這種能解析所有的視圖,即永遠能返回一個非空View對象的ViewResolver一定要把它放在ViewResolver鏈的最後面。

轉自:http://elim.iteye.com/blog/1770554
http://www.cnblogs.com/liruiloveparents/p/5054605.html

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