javascript
Spring MVC中的视图解析ViewResolver
http://blog.csdn.net/prince2270/article/details/5891085
在Spring MVC中,當(dāng)Controller將請求處理結(jié)果放入到ModelAndView中以后,DispatcherServlet會(huì)根據(jù)ModelAndView選擇合適的視圖進(jìn)行渲染。那么在Spring MVC中是如何選擇合適的View呢?View對象是是如何創(chuàng)建的呢?答案就在ViewResolver中,ViewResolver接口定義了resolverViewName方法,根據(jù)viewName創(chuàng)建合適類型的View實(shí)現(xiàn)。
??????? 那么,如何配置ViewResolver呢?在Spring中,ViewResolver作為Spring Bean存在,可以在Spring配置文件中進(jìn)行配置,例如下面的代碼,配置了jsp相關(guān)的viewResolver。
[xhtml] view plaincopyprint?<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"/><property name="suffix" value=".jsp"/></bean>
?????? 在Spring MVC中,因?yàn)閂iewResolver是使用bean來配置的,所以擴(kuò)展起來非常的容易,可以根據(jù)自己的需要定制ViewResolver,然后在配置文件中進(jìn)行相關(guān)的配置即可。
???????ViewResolver接口聲明了resolverViewName方法,這個(gè)方法的主要功能是根據(jù)ModelAndView中給定的viewName信息,再結(jié)合相關(guān)的配置,創(chuàng)建出合適類型的View對象。
???????ViewResolver接口是在DispatcherServlet中進(jìn)行調(diào)用的,當(dāng)DispatcherServlet調(diào)用完Controller后,會(huì)得到一個(gè)ModelAndView對象,然后DispatcherServlet會(huì)調(diào)用render方法進(jìn)行視圖渲染。
[java] view plaincopyprint?protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {// Determine locale for request and apply it to the response.Locale locale = this.localeResolver.resolveLocale(request);response.setLocale(locale);View view;if (mv.isReference()) {// We need to resolve the view name.view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);if (view == null) {throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" +getServletName() + "'");}}else {// No need to lookup: the ModelAndView object contains the actual View object.view = mv.getView();if (view == null) {throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +"View object in servlet with name '" + getServletName() + "'");}}// Delegate to the View object for rendering.if (logger.isDebugEnabled()) {logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");}view.render(mv.getModelInternal(), request, response);}
??????? 在DispatcherServlet類中,init方法中已經(jīng)進(jìn)行了相關(guān)的初始化,配置的ViewResolver信息都存放在viewResolvers中。在render方法中調(diào)用resolverViewName方法,在這個(gè)方法中逐一調(diào)用ViewResolver去取得View對象。
[java] view plaincopyprint?protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,HttpServletRequest request) throws Exception {for (ViewResolver viewResolver : this.viewResolvers) {View view = viewResolver.resolveViewName(viewName, locale);if (view != null) {return view;}}return null;}
??????? 在這里需要關(guān)于ViewResolver的選擇是通過循環(huán)進(jìn)行的,只選擇第一個(gè)符合要求的,因此在定義ViewResolver時(shí),需要注意定義其優(yōu)先級。
????????下面就來著重關(guān)注一下ViewResolver的類結(jié)構(gòu)。
?
?
?????? 關(guān)于View對象的創(chuàng)建,不同的ViewResolver的解決方法是各部相同的。如BeanNameViewResolver是根據(jù)viewName選擇相應(yīng)名稱的bean(這里需要注意bean的scope,是否需要線程安全),而UrlBasedViewResolver則是使用反射機(jī)制,根據(jù)viewClass信息創(chuàng)建view對象,因此這個(gè)view不受IoC容器的管理。ContentNegotiationViewResolver中可以嵌套ViewResolver,根據(jù)不同的的請求類型選擇合適的ViewResolver。
?????? DispatcherServlet得到View對象后,即調(diào)用View的render方法,執(zhí)行真正的渲染工作。
?????? 最后,看一下View的類結(jié)構(gòu)圖。
?
?????? 有上述的View類結(jié)構(gòu)圖可知,Spring已經(jīng)為我們提供了一系列可用的View。同時(shí),如果當(dāng)前提供的View不能滿足我們的要求時(shí),可以通過實(shí)現(xiàn)View接口進(jìn)行擴(kuò)展。如需要根據(jù)model中的數(shù)據(jù)使用JFreeChart繪圖,或者將這些數(shù)據(jù)作為文件下載時(shí),我們可以擴(kuò)展出JFreeChartView和FileDownloadView等,這樣就能更靈活的將同一份數(shù)據(jù)用不同的方式展現(xiàn)出來。
?
?
============
http://haohaoxuexi.iteye.com/blog/1770554
SpringMVC視圖解析器
前言
?? 在前一篇博客中講了SpringMVC的Controller控制器,在這篇博客中將接著介紹一下SpringMVC視圖解析器。當(dāng)我們對SpringMVC控制的資源發(fā)起請求時(shí),這些請求都會(huì)被SpringMVC的DispatcherServlet處理,接著Spring會(huì)分析看哪一個(gè)HandlerMapping定義的所有請求映射中存在對該請求的最合理的映射。然后通過該HandlerMapping取得其對應(yīng)的Handler,接著再通過相應(yīng)的HandlerAdapter處理該Handler。HandlerAdapter在對Handler進(jìn)行處理之后會(huì)返回一個(gè)ModelAndView對象。在獲得了ModelAndView對象之后,Spring就需要把該View渲染給用戶,即返回給瀏覽器。在這個(gè)渲染的過程中,發(fā)揮作用的就是ViewResolver和View。當(dāng)Handler返回的ModelAndView中不包含真正的視圖,只返回一個(gè)邏輯視圖名稱的時(shí)候,ViewResolver就會(huì)把該邏輯視圖名稱解析為真正的視圖View對象。View是真正進(jìn)行視圖渲染,把結(jié)果返回給瀏覽器的。
ViewResolver和View介紹
SpringMVC用于處理視圖最重要的兩個(gè)接口是ViewResolver和View。ViewResolver的主要作用是把一個(gè)邏輯上的視圖名稱解析為一個(gè)真正的視圖,SpringMVC中用于把View對象呈現(xiàn)給客戶端的是View對象本身,而ViewResolver只是把邏輯視圖名稱解析為對象的View對象。View接口的主要作用是用于處理視圖,然后返回給客戶端。
Spring為我們提供了非常多的視圖解析器,下面將列舉一些視圖解析器。
AbstractCachingViewResolver:這是一個(gè)抽象類,這種視圖解析器會(huì)把它曾經(jīng)解析過的視圖保存起來,然后每次要解析視圖的時(shí)候先從緩存里面找,如果找到了對應(yīng)的視圖就直接返回,如果沒有就創(chuàng)建一個(gè)新的視圖對象,然后把它放到一個(gè)用于緩存的map中,接著再把新建的視圖返回。使用這種視圖緩存的方式可以把解析視圖的性能問題降到最低。
UrlBasedViewResolver:它是對ViewResolver的一種簡單實(shí)現(xiàn),而且繼承了AbstractCachingViewResolver,主要就是提供的一種拼接URL的方式來解析視圖,它可以讓我們通過prefix屬性指定一個(gè)指定的前綴,通過suffix屬性指定一個(gè)指定的后綴,然后把返回的邏輯視圖名稱加上指定的前綴和后綴就是指定的視圖URL了。如prefix=/WEB-INF/jsps/,suffix=.jsp,返回的視圖名稱viewName=test/indx,則UrlBasedViewResolver解析出來的視圖URL就是/WEB-INF/jsps/test/index.jsp。默認(rèn)的prefix和suffix都是空串。URLBasedViewResolver支持返回的視圖名稱中包含redirect:前綴,這樣就可以支持URL在客戶端的跳轉(zhuǎn),如當(dāng)返回的視圖名稱是”redirect:test.do”的時(shí)候,URLBasedViewResolver發(fā)現(xiàn)返回的視圖名稱包含”redirect:”前綴,于是把返回的視圖名稱前綴”redirect:”去掉,取后面的test.do組成一個(gè)RedirectView,RedirectView中將把請求返回的模型屬性組合成查詢參數(shù)的形式組合到redirect的URL后面,然后調(diào)用HttpServletResponse對象的sendRedirect方法進(jìn)行重定向。同樣URLBasedViewResolver還支持forword:前綴,對于視圖名稱中包含forword:前綴的視圖名稱將會(huì)被封裝成一個(gè)InternalResourceView對象,然后在服務(wù)器端利用RequestDispatcher的forword方式跳轉(zhuǎn)到指定的地址。使用UrlBasedViewResolver的時(shí)候必須指定屬性viewClass,表示解析成哪種視圖,一般使用較多的就是InternalResourceView,利用它來展現(xiàn)jsp,但是當(dāng)我們使用JSTL的時(shí)候我們必須使用JstlView。下面是一段UrlBasedViewResolver的定義,根據(jù)該定義,當(dāng)返回的邏輯視圖名稱是test的時(shí)候,UrlBasedViewResolver將把邏輯視圖名稱加上定義好的前綴和后綴,即“/WEB-INF/test.jsp”,然后新建一個(gè)viewClass屬性指定的視圖類型予以返回,即返回一個(gè)url為“/WEB-INF/test.jsp”的InternalResourceView對象。
Xml代碼 ??
InternalResourceViewResolver:它是URLBasedViewResolver的子類,所以URLBasedViewResolver支持的特性它都支持。在實(shí)際應(yīng)用中InternalResourceViewResolver也是使用的最廣泛的一個(gè)視圖解析器。那么InternalResourceViewResolver有什么自己獨(dú)有的特性呢?單從字面意思來看,我們可以把InternalResourceViewResolver解釋為內(nèi)部資源視圖解析器,這就是InternalResourceViewResolver的一個(gè)特性。InternalResourceViewResolver會(huì)把返回的視圖名稱都解析為InternalResourceView對象,InternalResourceView會(huì)把Controller處理器方法返回的模型屬性都存放到對應(yīng)的request屬性中,然后通過RequestDispatcher在服務(wù)器端把請求forword重定向到目標(biāo)URL。比如在InternalResourceViewResolver中定義了prefix=/WEB-INF/,suffix=.jsp,然后請求的Controller處理器方法返回的視圖名稱為test,那么這個(gè)時(shí)候InternalResourceViewResolver就會(huì)把test解析為一個(gè)InternalResourceView對象,先把返回的模型屬性都存放到對應(yīng)的HttpServletRequest屬性中,然后利用RequestDispatcher在服務(wù)器端把請求forword到/WEB-INF/test.jsp。這就是InternalResourceViewResolver一個(gè)非常重要的特性,我們都知道存放在/WEB-INF/下面的內(nèi)容是不能直接通過request請求的方式請求到的,為了安全性考慮,我們通常會(huì)把jsp文件放在WEB-INF目錄下,而InternalResourceView在服務(wù)器端跳轉(zhuǎn)的方式可以很好的解決這個(gè)問題。下面是一個(gè)InternalResourceViewResolver的定義,根據(jù)該定義當(dāng)返回的邏輯視圖名稱是test的時(shí)候,InternalResourceViewResolver會(huì)給它加上定義好的前綴和后綴,組成“/WEB-INF/test.jsp”的形式,然后把它當(dāng)做一個(gè)InternalResourceView的url新建一個(gè)InternalResourceView對象返回。
Xml代碼 ??
XmlViewResolver:它繼承自AbstractCachingViewResolver抽象類,所以它也是支持視圖緩存的。XmlViewResolver需要給定一個(gè)xml配置文件,該文件將使用和Spring的bean工廠配置文件一樣的DTD定義,所以其實(shí)該文件就是用來定義視圖的bean對象的。在該文件中定義的每一個(gè)視圖的bean對象都給定一個(gè)名字,然后XmlViewResolver將根據(jù)Controller處理器方法返回的邏輯視圖名稱到XmlViewResolver指定的配置文件中尋找對應(yīng)名稱的視圖bean用于處理視圖。該配置文件默認(rèn)是/WEB-INF/views.xml文件,如果不使用默認(rèn)值的時(shí)候可以在XmlViewResolver的location屬性中指定它的位置。XmlViewResolver還實(shí)現(xiàn)了Ordered接口,因此我們可以通過其order屬性來指定在ViewResolver鏈中它所處的位置,order的值越小優(yōu)先級越高。以下是使用XmlViewResolver的一個(gè)示例:
(1)在SpringMVC的配置文件中加入XmlViewResolver的bean定義。使用location屬性指定其配置文件所在的位置,order屬性指定當(dāng)有多個(gè)ViewResolver的時(shí)候其處理視圖的優(yōu)先級。關(guān)于ViewResolver鏈的問題將在后續(xù)內(nèi)容中講到。
Xml代碼 ??
(2)在XmlViewResolver對應(yīng)的配置文件中配置好所需要的視圖定義。在下面的代碼中我們就配置了一個(gè)名為internalResource的InternalResourceView,其url屬性為“/index.jsp”。
Xml代碼 ??
(3)定義一個(gè)返回的邏輯視圖名稱為在XmlViewResolver配置文件中定義的視圖名稱——internalResource。
Java代碼 ??
(4)這樣當(dāng)我們訪問到上面定義好的testXmlViewResolver處理器方法的時(shí)候返回的邏輯視圖名稱為“internalResource”,這時(shí)候Spring就會(huì)到定義好的views.xml中尋找id或name為“internalResource”的bean對象予以返回,這里Spring找到的是一個(gè)url為“/index.jsp”的InternalResourceView對象。
BeanNameViewResolver:這個(gè)視圖解析器跟XmlViewResolver有點(diǎn)類似,也是通過把返回的邏輯視圖名稱去匹配定義好的視圖bean對象。不同點(diǎn)有二,一是BeanNameViewResolver要求視圖bean對象都定義在Spring的application context中,而XmlViewResolver是在指定的配置文件中尋找視圖bean對象,二是BeanNameViewResolver不會(huì)進(jìn)行視圖緩存。看一個(gè)例子,在SpringMVC的配置文件中定義了一個(gè)BeanNameViewResolver視圖解析器和一個(gè)id為test的InternalResourceview bean對象。
Xml代碼 ??
這樣當(dāng)返回的邏輯視圖名稱是 test的時(shí)候,就會(huì)解析為上面定義好id為test的InternalResourceView。
ResourceBundleViewResolver:它和XmlViewResolver一樣,也是繼承自AbstractCachingViewResolver,但是它緩存的不是視圖,這個(gè)會(huì)在后面有說到。和XmlViewResolver一樣它也需要有一個(gè)配置文件來定義邏輯視圖名稱和真正的View對象的對應(yīng)關(guān)系,不同的是ResourceBundleViewResolver的配置文件是一個(gè)屬性文件,而且必須是放在classpath路徑下面的,默認(rèn)情況下這個(gè)配置文件是在classpath根目錄下的views.properties文件,如果不使用默認(rèn)值的話,則可以通過屬性baseName或baseNames來指定。baseName只是指定一個(gè)基名稱,Spring會(huì)在指定的classpath根目錄下尋找以指定的baseName開始的屬性文件進(jìn)行View解析,如指定的baseName是base,那么base.properties、baseabc.properties等等以base開始的屬性文件都會(huì)被Spring當(dāng)做ResourceBundleViewResolver解析視圖的資源文件。ResourceBundleViewResolver使用的屬性配置文件的內(nèi)容類似于這樣:
Properties代碼 ??
在這個(gè)配置文件中我們定義了兩個(gè)InternalResourceView對象,一個(gè)的名稱是resourceBundle,對應(yīng)URL是/index.jsp,另一個(gè)名稱是test,對應(yīng)的URL是/test.jsp。從這個(gè)定義來看我們可以知道resourceBundle是對應(yīng)的視圖名稱,使用resourceBundle.(class)來指定它對應(yīng)的視圖類型,resourceBundle.url指定這個(gè)視圖的url屬性。會(huì)思考的讀者看到這里可能會(huì)有這樣一個(gè)問題:為什么resourceBundle的class屬性要用小括號包起來,而它的url屬性就不需要呢?這就需要從ResourceBundleViewResolver進(jìn)行視圖解析的方法來說了。ResourceBundleViewResolver還是通過bean工廠來獲得對應(yīng)視圖名稱的視圖bean對象來解析視圖的。那么這些bean從哪里來呢?就是從我們定義的properties屬性文件中來。在ResourceBundleViewResolver第一次進(jìn)行視圖解析的時(shí)候會(huì)先new一個(gè)BeanFactory對象,然后把properties文件中定義好的屬性按照它自身的規(guī)則生成一個(gè)個(gè)的bean對象注冊到該BeanFactory中,之后會(huì)把該BeanFactory對象保存起來,所以ResourceBundleViewResolver緩存的是BeanFactory,而不是直接的緩存從BeanFactory中取出的視圖bean。然后會(huì)從bean工廠中取出名稱為邏輯視圖名稱的視圖bean進(jìn)行返回。接下來就講講Spring通過properties文件生成bean的規(guī)則。它會(huì)把properties文件中定義的屬性名稱按最后一個(gè)點(diǎn)“.”進(jìn)行分割,把點(diǎn)前面的內(nèi)容當(dāng)做是bean名稱,點(diǎn)后面的內(nèi)容當(dāng)做是bean的屬性。這其中有幾個(gè)特別的屬性,Spring把它們用小括號包起來了,這些特殊的屬性一般是對應(yīng)的attribute,但不是bean對象所有的attribute都可以這樣用。其中(class)是一個(gè),除了(class)之外,還有(scope)、(parent)、(abstract)、(lazy-init)。而除了這些特殊的屬性之外的其他屬性,Spring會(huì)把它們當(dāng)做bean對象的一般屬性進(jìn)行處理,就是bean對象對應(yīng)的property。所以根據(jù)上面的屬性配置文件將生成如下兩個(gè)bean對象:
Xml代碼 ??
從ResourceBundleViewResolver使用的配置文件我們可以看出,它和XmlViewResolver一樣可以解析多種不同類型的View,因?yàn)樗鼈兊腣iew是通過配置的方式指定的,這也就意味著我們可以指定A視圖是InternalResourceView,B視圖是JstlView。
來看下面這個(gè)一個(gè)例子,我在SpringMVC的配置文件中定義了一個(gè)ResourceBundleViewResolver對象,指定其baseName為views,然后order為1。
Xml代碼 ??
我在classpath的根目錄下有兩個(gè)屬性文件,一個(gè)是views.properties,一個(gè)是views_abc.properties,它們的內(nèi)容分別如下:
views.properties:
Properties代碼 ??
views_abc.properties:
Properties代碼 ??
定義了如下這樣一個(gè)Controller,它有三個(gè)處理器方法。
Java代碼 ??
那么當(dāng)我們請求/mytest/resourceBundle.do的時(shí)候,ResourceBundleViewResolver會(huì)首先嘗試著來解析該視圖,這里Controller處理器方法返回的邏輯視圖名稱是resourceBundle,ResourceBundleViewResolver按照上面提到的解析方法進(jìn)行解析,這個(gè)時(shí)候它發(fā)現(xiàn)它是可以解析的,然后就返回了一個(gè)url為/index.jsp的InternalResourceView對象。同樣,請求/mytest/testResourceBundle.do返回的邏輯視圖test和/mytest/abc.do返回的邏輯視圖abc它都可以解析。當(dāng)我們把basename指定為包的形式,如“com.tiantian.views”,的時(shí)候Spring會(huì)按照點(diǎn)“.”劃分為目錄的形式,到classpath相應(yīng)目錄下去尋找basename開始的配置文件,如上面我們指定basename為“com.tiantian.views”,那么spring就會(huì)到classpath下的com/tiantian目錄下尋找文件名以views開始的properties文件作為解析視圖的配置文件。
FreeMarkerViewResolver、VolocityViewResolver:這兩個(gè)視圖解析器都是UrlBasedViewResolver的子類。FreeMarkerViewResolver會(huì)把Controller處理方法返回的邏輯視圖解析為FreeMarkerView,而VolocityViewResolver會(huì)把返回的邏輯視圖解析為VolocityView。因?yàn)檫@兩個(gè)視圖解析器類似,所以這里我就只挑FreeMarkerViewResolver來做一個(gè)簡單的講解。FreeMarkerViewResolver和VilocityViewResolver都繼承了UrlBasedViewResolver。
對于FreeMarkerViewResolver而言,它會(huì)按照UrlBasedViewResolver拼接URL的方式進(jìn)行視圖路徑的解析。但是使用FreeMarkerViewResolver的時(shí)候不需要我們指定其viewClass,因?yàn)镕reeMarkerViewResolver中已經(jīng)把viewClass定死為FreeMarkerView了。
我們先在SpringMVC的配置文件里面定義一個(gè)FreeMarkerViewResolver視圖解析器,并定義其解析視圖的order順序?yàn)?。
Xml代碼 ??
那么當(dāng)我們請求的處理器方法返回一個(gè)邏輯視圖名稱viewName的時(shí)候,就會(huì)被該視圖處理器加上前后綴解析為一個(gè)url為“fm_viewName.ftl”的FreeMarkerView對象。對于FreeMarkerView我們需要給定一個(gè)FreeMarkerConfig的bean對象來定義FreeMarker的配置信息。FreeMarkerConfig是一個(gè)接口,Spring已經(jīng)為我們提供了一個(gè)實(shí)現(xiàn),它就是FreeMarkerConfigurer。我們可以通過在SpringMVC的配置文件里面定義該bean對象來定義FreeMarker的配置信息,該配置信息將會(huì)在FreeMarkerView進(jìn)行渲染的時(shí)候使用到。對于FreeMarkerConfigurer而言,我們最簡單的配置就是配置一個(gè)templateLoaderPath,告訴Spring應(yīng)該到哪里尋找FreeMarker的模板文件。這個(gè)templateLoaderPath也支持使用“classpath:”和“file:”前綴。當(dāng)FreeMarker的模板文件放在多個(gè)不同的路徑下面的時(shí)候,我們可以使用templateLoaderPaths屬性來指定多個(gè)路徑。在這里我們指定模板文件是放在“/WEB-INF/freemarker/template”下面的。
Xml代碼 ??
接下來我們定義如下一個(gè)Controller:
Java代碼 ??
由上面的定義我們可以看到這個(gè)Controller的處理器方法freemarker返回的邏輯視圖名稱是“freemarker”。那么如果我們需要把該freemarker視圖交給FreeMarkerViewResolver來解析的話,我們就需要根據(jù)上面的定義,在模板路徑下定義視圖對應(yīng)的模板,即在“/WEB-INF/freemarker/template”目錄下建立fm_freemarker.ftl模板文件。這里我們定義其內(nèi)容如下:
Ftl代碼 ??
經(jīng)過上面的定義當(dāng)我們訪問/mytest/freemarker.do的時(shí)候就會(huì)返回一個(gè)邏輯視圖名稱為“freemarker”的ModelAndView對象,根據(jù)定義好的視圖解析的順序,首先進(jìn)行視圖解析的是FreeMarkerViewResolver,這個(gè)時(shí)候FreeMarkerViewResolver會(huì)試著解析該視圖,根據(jù)它自身的定義,它會(huì)先解析到該視圖的URL為fm_freemarker.ftl,然后它會(huì)看是否能夠?qū)嵗撘晥D對象,即在定義好的模板路徑下是否有該模板存在,如果有則返回該模板對應(yīng)的FreeMarkerView。在這里的話/WEB-INF/freemarker/template目錄下是存在模板文件fm_freemarker.ftl的,所以會(huì)返回一個(gè)url為fm_freemarker.ftl的FreeMarkerView對象。接著FreeMarkerView就可以利用該模板文件進(jìn)行視圖的渲染了。所以訪問結(jié)果應(yīng)該如下所示:
?
?
視圖解析器鏈
?????? 在SpringMVC中可以同時(shí)定義多個(gè)ViewResolver視圖解析器,然后它們會(huì)組成一個(gè)ViewResolver鏈。當(dāng)Controller處理器方法返回一個(gè)邏輯視圖名稱后,ViewResolver鏈將根據(jù)其中ViewResolver的優(yōu)先級來進(jìn)行處理。所有的ViewResolver都實(shí)現(xiàn)了Ordered接口,在Spring中實(shí)現(xiàn)了這個(gè)接口的類都是可以排序的。在ViewResolver中是通過order屬性來指定順序的,默認(rèn)都是最大值。所以我們可以通過指定ViewResolver的order屬性來實(shí)現(xiàn)ViewResolver的優(yōu)先級,order屬性是Integer類型,order越小,對應(yīng)的ViewResolver將有越高的解析視圖的權(quán)利,所以第一個(gè)進(jìn)行解析的將是ViewResolver鏈中order值最小的那個(gè)。當(dāng)一個(gè)ViewResolver在進(jìn)行視圖解析后返回的View對象是null的話就表示該ViewResolver不能解析該視圖,這個(gè)時(shí)候如果還存在其他order值比它大的ViewResolver就會(huì)調(diào)用剩余的ViewResolver中的order值最小的那個(gè)來解析該視圖,依此類推。當(dāng)ViewResolver在進(jìn)行視圖解析后返回的是一個(gè)非空的View對象的時(shí)候,就表示該ViewResolver能夠解析該視圖,那么視圖解析這一步就完成了,后續(xù)的ViewResolver將不會(huì)再用來解析該視圖。當(dāng)定義的所有ViewResolver都不能解析該視圖的時(shí)候,Spring就會(huì)拋出一個(gè)異常。
?????? 基于Spring支持的這種ViewResolver鏈模式,我們就可以在SpringMVC應(yīng)用中同時(shí)定義多個(gè)ViewResolver,給定不同的order值,這樣我們就可以對特定的視圖特定處理,以此來支持同一應(yīng)用中有多種視圖類型。注意:像InternalResourceViewResolver這種能解析所有的視圖,即永遠(yuǎn)能返回一個(gè)非空View對象的ViewResolver一定要把它放在ViewResolver鏈的最后面。
?
Xml代碼 ??
===============
http://luliqu2005.blog.163.com/blog/static/18638271020129122434944/
springMVC @Resource @Autowired 區(qū)別??
2012-10-12 14:43:49|??分類: 默認(rèn)分類 |??標(biāo)簽: |字號大中小?訂閱
@Autowired注解是按類型裝配依賴對象,默認(rèn)情況下它要求依賴對象必須存在,如果允許null值,可以設(shè)置它required屬性為false。如果我們想使用按名稱裝配,可以結(jié)合@Qualifier注解一起使用。如下:??? @Autowired @Qualifier("personDaoBean")??
? private PersonDao personDao;??
@Resource注解和@Autowired一樣,也可以標(biāo)注在字段或?qū)傩缘膕etter方法上,但它默認(rèn)按名稱裝配。名稱可以通過@Resource的name屬性指定,如果沒有指定name屬性,當(dāng)注解標(biāo)注在字段上,即默認(rèn)取字段的名稱作為bean名稱尋找依賴對象,當(dāng)注解標(biāo)注在屬性的setter方法上,即默認(rèn)取屬性名作為bean名稱尋找依賴對象。??
? @Resource(name=“personDaoBean”)??
? private PersonDao personDao;//用于字段上??
注意:如果沒有指定name屬性,并且按照默認(rèn)的名稱仍然找不到依賴對象時(shí), @Resource注解會(huì)回退到按類型裝配。但一旦指定了name屬性,就只能按名稱裝配了。
?
總結(jié)
以上是生活随笔為你收集整理的Spring MVC中的视图解析ViewResolver的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAX-WS Web Service
- 下一篇: SpringMVC + spring3.