Spring MVC使用ViewResolver來根據controller中返回的view名關聯到具體的View對象。使用View對象來渲染返回值以生成最終的視圖,如html,json或pdf等。
Spring MVC中,通過在servlet context配置文件中配置的ViewResolver Bean對象來注冊ViewResolver對象,其在spring mvc的dispatcherServlet中的使用過程其實和之前提到的HandlerMapping和HanderAdapter類似。
DispatcherServlet初始化時,首先根據當前context中注冊的Beans中實現了ViewResolver接口的Bean列表來生成ViewResolver對象列表,並根據這些ViewResolver中的order屬性進行排序,如果沒配置order屬性則此ViewResolver的優先級最低。
當HandlerAdapter調用完畢handler method返回view對象時,dispatcherServlet將根據當前已經注冊了的ViewResolver列表的順序去調用其中的resolveViewName方法,以根據viewName找到實際對應的View對象,並根據第一個返回的View對象中的render方法來生成最終的用戶視圖。
與HandlerMapping和HanderAdapter類似,DispatcherServlet也提供了參數來允許用戶指定是否只加載自己的ViewResolver,當屬性detectAllViewResolvers設置為false時,則spring mvc將查找名為viewResolver的bean 來作為當前唯一的ViewResolver。
<init-param>
<param-name>detectAllViewResolvers</param-name>
<param-value>false</param-value>
</init-param>
UrlBasedViewResolver與InternalResourceViewResolver
之前的例子中,為將返回的viewname映射到對應的jsp上,在servlet context 配置文件中是這么定義的
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
這個定義的含義是指UrlBasedViewResolver將使用JstlView對象來渲染結果,並將handler method返回的modelAndView基礎上,加上目錄前綴/WEB-INF/jsp/和文件名稱后綴.jsp。例如結果返回的viewName為helloworld,則對應的實際jsp為/WEB-INF/jsp/helloworld.jsp
當返回的viewName的前綴為forward:時,spring mvc將結果通過forward的方式轉到對應的視圖,例如forward:helloworld。這也是spring mvc缺省的使用模式。
當返回的viewName的前綴為redirect:時,spring mvc將結果通過redirect的方式轉到對應的視圖。例如redirect:helloworld
InternalResourceViewResolver為UrlBasedViewResolver的子類,它將InternalResourceView作為缺省的View類,如果當前classpath中有jstl的jar包時則使用JstlView作為缺省的view來渲染結果。因此以下使用InternalResourceViewResolver的定義應該和之前使用UrlBasedViewResolver定義的viewresolver的作用相同。
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
除此之外,InternalResourceViewResolver還提供了
alwaysInclude屬性來要求返回的結果使用include方式而不是forward方式
exposeContextBeansAsAttributes屬性以將當前spring 環境中的 beans作為request attritbutes來暴露到頁面上。
exposedContextBeanNames屬性來限制能夠暴露到頁面上的spring bean的名稱列表。