DispatcherServlet 會根據傳回的ModelAndView實例來解析View名稱,並處理用以呈現於畫面的資料Model物件。View名稱的解析是委託給實作 org.springframework.web.servlet.ViewResolver介面的實例,ViewResolver介面定義如下:
package org.springframework.web.servlet;
import java.util.Locale;
public interface ViewResolver {
View resolveViewName(String, Locale locale)
throws ServletException;
}
import java.util.Locale;
public interface ViewResolver {
View resolveViewName(String, Locale locale)
throws ServletException;
}
ViewResolver的一個實例是InternalResourceViewResolver,您可以在viewResolver中設定 "prefix"與"suffix"屬性,分別設定除了路徑的前置與後置文字,這樣您的viewPage屬性就可以只打路徑的主要區別名稱,直接給個設定 的示範:
...
<bean id="viewResolver"
class="org.springframework.web.servlet.
→ view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
...
<bean id="viewResolver"
class="org.springframework.web.servlet.
→ view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
...
ViewResolve在名稱解析完之後,實際的View繪製與Model資料物件的轉換處理是交給實作org.springframework.web.servlet.View介面的實例,View介面定義如下:
package org.springframework.web.servlet;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface View {
void render(Map model, HttpServletRequest request,
HttpServletResponse response) throws Exception;
}
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface View {
void render(Map model, HttpServletRequest request,
HttpServletResponse response) throws Exception;
}
例如InternalResourceViewResolver預設的"viewClass"是InternalResourceView,您也可以設定 "viewClass"屬性為其它的View層技術相關類別,例如設定為 org.springframework.web.servlet.view.JstlView,另外還有TilesView、VelocityView 等實作類別,可適用不同的View技術。
您可以使用org.springframework.web.servlet.view.BeanNameViewResolver,例如:
...
<bean id="viewResolver"
class="org.springframework.web.servlet.
→ view.BeanNameViewResolver"/>
<bean id="hello"
class="org.springframework.web.servlet.
→ view.JstlView">
<property name="url">
<value>/WEB-INF/jsp/hello.jsp</value>
</property>
</bean>
...
<bean id="viewResolver"
class="org.springframework.web.servlet.
→ view.BeanNameViewResolver"/>
<bean id="hello"
class="org.springframework.web.servlet.
→ view.JstlView">
<property name="url">
<value>/WEB-INF/jsp/hello.jsp</value>
</property>
</bean>
...
在以上的設定中,當ModelAndView返回的view名稱為"hello"時,會去尋找"id"屬性為hello的View Bean。
您也可以將ViewResolver的定義獨立出來至一個屬性檔中,這可以使用 org.springframework.web.servlet.view.ResourceBundleViewResolver來達成,這樣作的好 處是,您可以根據您實際的URL去處設定不同的表示層技術,例如:
...
<bean id="viewResolver"
class="org.springframework.web.servlet.
→ view.ResourceBundleViewResolver">
<property name="basename">
<value>views</value>
</property>
</bean>
...
<bean id="viewResolver"
class="org.springframework.web.servlet.
→ view.ResourceBundleViewResolver">
<property name="basename">
<value>views</value>
</property>
</bean>
...
在ResourceBundleViewResolver的"basename"屬性設定了"views"名稱(實際上,"views"也是 "basename"的預設值),這表示將使用views.properties來設定表示層技術的"viewClass"與"url",例如一個 views.properties的撰寫範例如下所示:
hello.class=org.springframework.web.servlet.view.InternalResourceView
hello.url=/WEB-INF/jsp/hello.jsp
welcome.class=org.springframework.web.servlet.view.JstlView
welcome.url=/WEB-INF/jsp/welcome.jsp
other.class=org.springframework.web.servlet.view.VelocityView
other.url=/WEB-INF/vm/other.vm
hello.url=/WEB-INF/jsp/hello.jsp
welcome.class=org.springframework.web.servlet.view.JstlView
welcome.url=/WEB-INF/jsp/welcome.jsp
other.class=org.springframework.web.servlet.view.VelocityView
other.url=/WEB-INF/vm/other.vm
在返回的ModelAndView實例中的view名稱若為"hello",則會尋找hello.class及hello.url來得到對應的 ViewClass實例及指定的目標URL,使用.properties的好處是,您可以為不同的國家或地區設置不同的View,在"basename" 上設置為"views",表示預設會讀取views.properties,如果語系設定是en_US的,事實上您可以為它準備 views_en_US.properties,同樣的,如果語系設定是zh_TW的,可以為它準備views_zh_TW.properties,而對 應的檔案中可以設置與區域設定物件Locale相關的View。
您也可以使用org.springframework.web.servlet.view.XmlViewResolver,例如一個設定的範例如下所示:
...
<bean id="viewResolver"
class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location">
<value>/WEB-INF/demo-views.xml</value>
</property>
</bean>
...
<bean id="viewResolver"
class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location">
<value>/WEB-INF/demo-views.xml</value>
</property>
</bean>
...
在上面的設定中,"location"屬性預設是views.xml,這邊設定為demo-views.xml,表示到demo-views.xml中尋找View的Bean定義,例如在demo-views.xml中這麼定義:
...
<bean id="hello"
class="org.springframework.web.servlet.view.JstlView">
<property name="url">
<value>/WEB-INF/jsp/hello.jsp</value>
</property>
</bean>
...
<bean id="hello"
class="org.springframework.web.servlet.view.JstlView">
<property name="url">
<value>/WEB-INF/jsp/hello.jsp</value>
</property>
</bean>
...
其運作的機制與設定BeanNameViewResolver時是類似的,當返回的ModelAndView 實例中的view名稱為"hello"時,則會去尋找Bean定義中的"id"為"hello"的View設定。