SpringMVC流程之View與ViewResolver

1、簡介

不少朋友可能疑惑過,在SpringMVC中爲何一樣是返回一個字符串,有的前端獲得的是頁面,有的獲得是json數據。 handler 由於使用了不一樣的Handler,有@ResponseBody註解的使用了RequestResponseBodyMethodProcessor,後一個方法使用了ViewNameMethodReturnValueHandler。前端

固然,它們都是HandlerMethodReturnValueHandler,SpringMVC到底怎麼玩的呢?web

咱們來看一個簡化版本的流程圖,能夠幫助咱們快速理清楚脈絡,避免被龐雜的代碼繞暈。spring

MVC流程圖知道了MVC的大體流程,咱們就來重點關注一下ViewResolver部分json

2、ViewResolver

ViewResolver用於解決從邏輯視圖到View,通常邏輯視圖就是viewName,就是根據返回的字符串找到對應的View。緩存

ViewResolver的繼承結構

2.1 AbstractCachingViewResolver

AbstractCachingViewResolver一看就知道是一個抽象類,專門爲繼承設計的。jsp

它作的最重要的工做就是緩存,就是把已經解析過的視圖保存起來,這樣能夠避免每一次解析。url

2.2 UrlBasedViewResolver

UrlBasedViewResolver繼承了AbstractCachingViewResolver,主要就是提供的一種拼接URL的方式來解析視圖。spa

能夠prefix、suffix來簡化視圖名稱,默認的prefix和suffix都是空。設計

URLBasedViewResolver支持"redirect:"前綴,經過轉換爲RedirectView實現,這樣就能夠支持URL在客戶端的跳轉code

URLBasedViewResolver支持"forword:"前綴,經過InternalResourceView實現。

<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>

2.3 InternalResourceViewResolver

InternalResourceViewResolver繼承了URLBasedViewResolver,因此URLBasedViewResolver支持的特性它都支持。

InternalResourceViewResolver和URLBasedViewResolver差很少,InternalResourceViewResolver主要就是獲取InternalResourceView,就是爲了處理JSP和JSTL的。

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

2.4 XmlViewResolver

XmlViewResolver直接繼承AbstractCachingViewResolver抽象類,因此它也是支持視圖緩存的。

xml不是解析xml的,而是用一個xml文件來配置,視圖名稱和View之間的對應關係,經過location屬性指定配置文件,默認/WEB-INF/views.xml。

<bean class="org.springframework.web.servlet.view.XmlViewResolver">
   <property name="location" value="/WEB-INF/views.xml"/>
   <property name="order" value="1"/>
</bean>

2.5 BeanNameViewResolver

BeanNameViewResolver和XmlViewResolver很像,就是經過視圖名稱(Controller中方法返回的字符串)去找作爲id去找View。

與XmlViewResolver不一樣的是,BeanNameViewResolver的View不用單獨寫xml文件了。

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">  
   <property name="order" value="1"/>  
</bean>
<bean id="index" class="org.springframework.web.servlet.view.InternalResourceView">  
   <property name="url" value="/index.jsp"/>  
</bean>

2.6 ResourceBundleViewResolver

ResourceBundleViewResolver就是XmlViewResolver的properties版本。

例如,下面的properties,等價於後面的xml配置

test1.(class)=org.springframework.web.servlet.view.InternalResourceView  
test1.url=/test1.jsp  
test2.(class)=org.springframework.web.servlet.view.InternalResourceView  
test2.url=/test2.jsp

等價於:

<bean id="test1" class="org.springframework.web.servlet.view.InternalResourceView">  
   <property name="url" value="/test1.jsp"/>  
</bean>  
<bean id="test2" class="org.springframework.web.servlet.view.InternalResourceView">  
   <property name="url" value="/test2.jsp"/>  
</bean>

ResourceBundleViewResolver的配置文件是一個屬性文件,並且必須是放在classpath路徑下面的,默認狀況下這個配置文件是在classpath根目錄下的views.properties文件。

能夠經過屬性baseName或baseNames來指定屬性文件名稱,Spring會在指定的classpath根目錄下尋找以指定的baseName開始的屬性文件進行View解析。

例如,baseName爲base,那麼base.properties、baseABC.properties、base123.properties等以base開始的屬性文件都會被Spring當作ResourceBundleViewResolver解析視圖的資源文件。

3、多個ViewResolver處理流程

在SpringMVC中通常會存在多個ViewResolver

DispatcherServlet初始化ViewResolver上面是DispatcherServlet初始化ViewResolver。

在SpringMVC中能夠同時定義多個ViewResolver視圖解析器,而後它們會組成一個ViewResolver鏈。

多個ViewResolver將根據ViewResolver的優先級來進行處理。

在ViewResolver中是經過order屬性來指定順序的,默認都是最大值。order越小,對應的ViewResolver優先級越高,因此第一個進行解析的將是ViewResolver鏈中order值最小的那個。

當一個ViewResolver在進行視圖解析後返回的View對象是null則表示該ViewResolver不能解析該視圖。

這個時候若是還存在其餘order值比它大的ViewResolver,就會調用剩餘的ViewResolver中的order值最小的那個來解析該視圖,依次調用。

當ViewResolver在進行視圖解析後返回的是一個非空的View對象的時候,視圖解析結束,若是沒有解析到有View,返回null。

這一部分邏輯在DispatcherServlet的resolveViewName方法中: resolveView邏輯 View部分是比較複雜的,可是通常也不多關注的,由於View部分更加在於的是細節,咱們看一下View的繼承結構圖。 View繼承結構

相關文章
相關標籤/搜索