入门 18 - DispatcherServlet定义档
DispatcherServlet预设使用servlet名称加上"-servlet.xml"作为其定义档名称,定义档预设是放在WEB-INF下,您也可以自行指定定义文件名称与位置,例如:
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/hello1-servlet.xml, /WEB-INF/hello2-servlet.xml</param-value>
</init-param>
</servlet>
DispatcherServlet各有其namespace与应用程序context,您可以在web.xml中定义多个DispatcherServlet的实例,分别负责不同模块的请求处理工作。
Spring对DispatcherServlet所处理的组件(component)都当作一般的Bean来处理,所以在设定 DispatcherServlet的定义档时,就如同之前的主题中处理Bean定义文件一样,一致性的组态方式是Spring所提供的优点之一,每个组件的设定都像是Bean,所以您只要查询API文件,了解属性的关系与作用,并在定义档中设定好依赖关系,就可以使用这些组件。
一些设定DispatcherServlet的定义档方式,我们前一个主题中介绍了大半,这边补充一些额外的设定。
首先,我们之前在设定helloUserAction,在设定viewPage时,必须设定好完整的目录与文件名称,例如:
<bean id="helloUserAction" class="onlyfun.caterpillar.HelloUserAction">
<property name="helloWord">
<value>Hello!</value>
</property>
<property name="viewPage">
<value>/WEB-INF/jsp/hellouser.jsp</value>
</property>
</bean>
您可以在viewResolver中设定prefix与suffix属性,分别设定除了文件名之外的前置与后置文字,这样您的viewPage属性就可以只打档案的主要名称,直接给个实例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hellouser.do">helloUserAction</prop>
</props>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.InternalResourceView</value>
</property>
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="helloUserAction" class="onlyfun.caterpillar.HelloUserAction">
<property name="helloWord">
<value>Hello!</value>
</property>
<property name="viewPage">
<value>hellouser</value>
</property>
</bean>
</beans>
您也可以将viewResolver的定义独立出来至一个属性文件中,使用 org.springframework.web.servlet.view.ResourceBundleViewResolver,这样作的好处是您可以根据您实际的url去处设定不同的表示层技术,例如:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hellouser.do">helloUserAction</prop>
</props>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename">
<value>views</value>
</property>
</bean>
<bean id="helloUserAction" class="onlyfun.caterpillar.HelloUserAction">
<property name="helloWord">
<value>Hello!</value>
</property>
<property name="viewPage">
<value>hellouser</value>
</property>
</bean>
</beans>
我们在ResourceBundleViewResolver的basename属性设定了views名称(实际上,views也是basename的 默认值),这表示我们将使用views.properties来设定表示层技术的viewClass与url,我们的views.properties如下:
hellouser.class=org.springframework.web.servlet.view.InternalResourceView
hellouser.url=/WEB-INF/jsp/hellouser.jsp
welcomeuser.class=org.springframework.web.servlet.view.JstlView
welcomeuser.url=/WEB-INF/jsp/welcomeuser.jsp
otherview.class=org.springframework.web.servlet.view.VelocityView
otherview.url=/WEB-INF/vm/other.vm
利用这个方式,我们可以混合不同的表示层技术在同一个Web应用程序中,views.properties中是class与url值设定,其 hellouser与welcomeuser的名称是我们给ModelAndView的名称,例如我们设定了hellouser给 ModelAndView的话,就会去找hellouser.class与hellouser.url来设定表示层技术与url去处,我们则在这边是透过 helloUserAction的viewPage属性来注入,避免将名称写死在程序中。
如果您的JSP网页或Servlet中会丢出例外,而您想捕捉这个例外,除了容器与JSP网页的设定方法之外(参考JSP/Servlet版面中的介 绍),您也可以在DispatcherServlet的定义档中设定错误处理网页,设定一个exceptionResolver Bean,例如SimpleMappingExceptionResolver:
....
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.InternalResourceView</value>
</property>
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.sql.SQLException">exsql</prop>
<prop key="java.sql.IOException">exio</prop>
</props>
</property>
</bean>
....
如此设定,只要发生了SQLException,就会连接至/WEB-INF/jsp/exsql.jsp,而发生了IOException,就会连接至/WEB-INF/jsp/exio.jsp。