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; }
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> ...
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; }
例如 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> ...
在以上的设定中,当 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> ...
在 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
在返回的 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> ...
在上面的设定中,"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> ...
其运作的机制与设定 BeanNameViewResolver 时是类似的,当返回的 ModelAndView 实例中的 view 名称为"hello"时,则会去寻找 Bean 定义中的"id"为"hello"的 View 设定。