在SpringMVC框架中,担任前端控制器的org.springframework.web.servlet.DispatcherServlet。Web.xml文件配置代码如下:
1<servlet>
2 <servlet-name>dispatcherServlet</servlet-name>
3 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
4 <init-param>
5 <param-name>contextConfigLocation</param-name>
6<param-value>/WEB-INF/applicationContext.xml</param-value>
7 </init-param>
8 <load-on-startup>1</load-on-startup>
9</servlet>
10
11<servlet-mapping>
12 <servlet-name>dispatcherServlet</servlet-name>
13 <url-pattern>*.do</url-pattern>
14</servlet-mapping>
DispatcherServlet负责分发请求至控制对象(Controller),控制对象要实现Controller接口中的handleRequest()方法:
ModelAndView handleRequest()HttpServletRequest request, HttpServletResponse response) throws Exception;
在web MVC架构下,控制对象的作用为收集使用者的请求,进行web层的相关操作,不应当在控制对象中执行业务逻辑,也不应当让Servlet相关的API浸入至业务层。
实际上,DispatcherServlet必须根据一个HandlerMapping对象,决定请求由哪一个Controller来处理,DispatcherServlet默认用BeanNameUrlHandlerMapping,也就是根据Bean在定义时的“name”属性及使用者请求的URL,决定使用哪个Controller实例。
在Controller返回ModelAndView后,DispatcherServlet会交由ViewR esolver对象来作View层的相关解析。例如InternalResourceViewResolver,需要设置viewClass,默认是org.springframework.web.servlet.view.InternalResourceView。
InternalResourceViewResolver的prefix和suffix属性会与ModelAndView返回的路径信息结合。
一个简单的Spring MVC的Hello world例子如下:
编写SayHelloController.java文件,实现Controller接口
1public class SayHelloController implements Controller {
2
3 private String viewPage;
4
5 public ModelAndView handleRequest(HttpServletRequest request,
6 HttpServletResponse response) throws Exception {
7 String username = request.getParameter("username");
8 return new ModelAndView(viewPage, "username", username);
9 }
10
11 public void setViewPage(String viewPage){
12 this.viewPage = viewPage;
13 }
14}
编写配置文件applicationContext.xml
1<bean id="viewResolver"
2 class="org.springframework.web.servlet.view.InternalResourceViewResolver">
3 <property name="prefix" value="/WEB-INF/" />
4 <property name="suffix" value=".jsp" />
5</bean>
6<bean name="/sayHello.do" class="SpringMVC.SayHelloController">
7 <property name="viewPage" value="sayHello"/>
8</bean>
9
项目的组织结构如下图:
Handler Mapping
BeanNameUrlHandlerMapping是简单的HandlerMapping,Spring中常用的是SimpleUrlHandlerMapping。
一段配置如下:
1<bean name="loggingInterceptor" class="SpringMVC.LoggingInterceptor"/>
2
3<bean id="urlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
4 <property name="interceptors">
5 <list>
6 <ref bean="loggingInterceptor"/>
7 </list>
8 </property>
9 <property name="mappings">
10 <props>
11 <prop key="/sayHello.do">sayHelloController</prop>
12 </props>
13 </property>
14</bean>
15
16<bean name="sayHelloController" class="SpringMVC.SayHelloController">
17 <property name="viewPage" value="sayHello"/>
18</bean>
Handler Interceptor
在执行Controller的前后,或是在View绘制之后打算作一些操作,可以实现HandlerInterceptor接口:
1public interface HandlerInterceptor {
2
3 public void afterCompletion(HttpServletRequest arg0,
4 HttpServletResponse arg1, Object arg2, Exception arg3)
5 throws Exception;
6
7 public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
8 Object arg2, ModelAndView arg3) throws Exception;
9
10 public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
11 Object arg2) throws Exception ;
12
13}
可以继承HandlerInterceptorAdapter,它实现了HandlerInterceptor接口。然后在xml文件中配置上上段代码。
ModelAndView
ModelAndView类代表了Spring MVC程序中,呈现画面所使用的Model数据对象与View数据对象。由于Java程序的方法中一次只能返回一个对象,所以ModelAndView的作用是封装这两个对象,方便同时返回Model与View。
Model可以用一个Map封装;View可以用一个简单字符串,也可以用一个实现了View接口的对象。一个实现View的实例是RediectView,它将使用重定向。而默认是使用转发。
View Resolver
View名称的解析是委托给实现ViewResolver接口的实例。其一个实例是InternalResourceViewResolver。
还有其他的如BeanNameViewResolver。当ModelAndView返回的view名称是“hello”时,会寻找id属性是hello的View Bean。
ViewResolver在名称解析完毕后,实际的View绘制于Model对象的转换处理时交给实现View接口的实例。例如InternalResourceViewResolver默认的viewClass是InternalResourceView。还有其他的如JstlView、TilesView、VelocityView等。