详解Spring Web MVC中的DispatcherServlet类

8 篇文章 0 订阅
Spring的Web MVC框架是围绕DispatcherServlet这个类设计的,DispatcherServlet是FrameworkServlet的子类,不仅完全与Spring的IoC容器紧密集成,而且允许开发人员充分利用Spring的每一种功能特性。

    在一个理想的MVC环境中,通信是单向的。但在实际应用中,当在一个 Web 应用程序中实现 MVC 时,Model、View 和 Controller 通常不会在单一的类中出现,而是被实现为紧密相关的对象群体。每一组对象执行一个特定的MVC 任务。Controller 可能由若干个类组成,它们被组合到一起,用于分析 HTTP或者WAP的 请求/响应并确定应用程序所需的动作。Model 几乎可以确定由多个类组成。而 View 在 Web 应用程序中通常是某种模板系统(例如JSP),而且也很可能由几个对象组成。在这种情况下,把应用程序流程控制集中在一个entry point是非常有意义是设计选择。集中化可以帮助客户了解一个复杂系统是如何运行的,而且它还提供了一个单独的入口,在那里可以插入全局代码,例如在Spring框架中通过插入某些advice,以AOP的方式实现日志管理、安全认证等具有共性的功能。

    DispatcherServlet本质上便是采用了前端控制器(Front Controller,有关内容可参考 http://www.microsoft.com/china/MSDN/library/architecture/patterns/esp/DesFrontController.mspx?mfr=true)这一设计模式对客户请求的处理进行了封装,对客户端而言,只需面对单一的处理入口,其处理流程如下图所示:




    DispatcherServlet作为Front Controllers需要将控制委托给Controller,而Controller 模式才是 MVC Controller 的真正核心所在。Controller 的首要职责就是决定应用程序应该如何响应请求。

    DispatcherServlet继承了HttpServlet类,并需要在web.xml文件中声明。经由DispatcherServlet处理的客户端请求也必须在同一个web.xml中定义URL映射,这是标准的Java EE Servlet配置方式,DispatcherServlet的声明与映射定义示例如下:
<web-app>
<servlet>
<servlet-name>exampleServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>        
<param-name>contextConfigLocation</param-name>        
<param-value>/WEB-INF/exampleServlet-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>exampleServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>

    在上述配置中,名为exampleServlet的DispatcherServlet将处理所以以.do结尾的HTTP请求,而对Controller和View模板的指派,将在exampleServlet-servlet.xml文件中进行配置。这其中体现了Spring一直倡导的IoC思想。

    在Spring中,每个DispatcherServlet都有自己的WebApplicationContext,并继承了所有在根部WebApplicationContext中所定义的bean,DispatcherServlet可以覆盖这些继承下来的bean,也可以定义特定servlet实例自己专用的bean,下图很好地说明了Spring Web MVC框架中的context层次结构:




    以上面的DispatcherServlet配置文件为例,当exampleServlet被初始化之后,Spring将在指定的WEB-INF目录寻找exampleServlet-servlet.xml文件,并创建由exampleServlet-servlet.xml定义的所有与MVC相关的bean。这个配置文件的存放路径当然是可以根据实际需要修改的。

    WebApplicationContext在ApplicationContext的基础上增加了对themes解析的支持,同时通过与ServletContext的链接可以获知具体与哪个servlet相关联。在设计DispatcherServlet时,需亚明确地将WebApplicationContext与ServletContext绑定在一起,通过RequestContextUtils类的静态方法,可以在需要时查询WebApplicationContext。

    为了处理客户端请求以及确定适当的表现视图,DispatcherServlet需要通过一些特殊的bean来完成。这些bean包含在Spring框架中,并与其他bean一样在WebApplicationContext中进行配置, 就多数bean而言,Spring已经提供了足够有效的配置信息通常不必再担心如何去配置它们。这些特殊的bean包括:
1.Controller,无疑这是最重要的一个bean,因为它就是MVC中的“C”。
2.Handler mappings,例如在处理由form提交的HTTP请求时常用的SimpleUrlHandlerMapping。这些bean需要在controller与URL模板之间实现映射,为特定的URL指派特定的controller进行后续处理,典型的SimpleUrlHandlerMapping映射配置如下:

<bean id="exampleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
        <prop key="/1.do">exampleController1</prop>
        <prop key="/2.do">exampleController2</prop>
        <prop key="/3.do">exampleController3</prop>
</props>
</property>
</bean>
    所有的Spring MVC的Handler mapping都实现了org.springframework.web.servlet.HandlerMapping接口:
      BeanNameUrlHandlerMapping---通过控制器的类名映射到URL.
      SimpleUrlHandlerMapping---通过配置文件定义的属性将控制器映射到URL
      CommonsPathMapHandlerMapping---通过控制器源代码中放置的metadata将控制器映射到URL,示例如下:
<bean id="urlMapping" class="org.springframework.web.servlet.handler.metadata.CommonsPathMapHandlerMapping"/>
/**
*@@org.springframework.web.servlet.handler.commonsattributes.PathMap("/1.do")
*/

public class exampleController1 extends AbstractCommandController
{
//…
}

3.View resolvers,Spring提供了许多View接口的实现,真正做到了与视图层的具体实现无关,视图解析器将视图的名字与实际的视图对应起来。在使用时,需要在配置文件中进行定义,例如:

<bean id="exampleViewResolver" 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>
4.Locale resolver,这些解析器为需要国际化的视图提供支持
5.Theme resolver,用于解析应用程序可能使用到的主题,以便提供个性化的布局、界面。
6.Multipart file resolver,这个bean专用于处理由HTML页面上传文件请求。
7.Handler exception resolver,顾名思义,这些bean用于将异常信息与视图映射起来,或者实现其他更复杂的异常处理代码。

    当一个DispatcherServlet配置完毕,处于工作状态时,它对一个客户端请求的处理过程需要经过如下流程,这在程序设计时需要认真考虑:

1. 搜索到WebApplicationContext,并将其绑定为客户请求的一个属性,以便controller或其他对象可以在处理过程中使用。缺省地,这将由DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE属性绑定。.
2. 将Locale resolver与此客户请求绑定,以便其他对象在处理请求时能够解析相应的国际化特性。当然,即便不使用Locale resolver也关系不大,毕竟很多时候是不需要国际化的。
3. 将Theme resolver与此客户请求绑定,以便视图类确定就是哪个主题。Theme resolver也是一个可选的解析器,若不需要,完全可以不用。
4. 若指定了一个Multipart resolver,则此客户请求将被封装在MultipartHttpServletRequest类。
5. 搜索一个合适的handler。若找到,则执行相应的代码序列(预处理,后处理,和控制器),从而准备获取一个可能发往视图的model。.
6. 若返回了一个model,则需要调用一个视图。若没有model返回(比如处于安全考虑),则不需调用视图,而此时,客户请求也已得到响应。

最后需要说明的是,开发人员可以在web.xml定义若干DispatcherServlet的初始化参数,例如contextConfigLocation。contextConfigLocation用于指定Spring配置文件的位置,在上面的例子我们已经看到这样的定义:
<init-param>      
<param-name>contextConfigLocation</param-name>      
<param-value>/WEB-INF/exampleServlet-servlet.xml</param-value>
</init-param>
如果有多个配置文件,则可以用逗号分隔开来,例如:
<init-param>      
<param-name>contextConfigLocation</param-name>      
<param-value>/WEB-INF/example1Servlet-servlet.xml,/WEB-INF/example2Servlet-servlet.xml</param-value>
</init-param>
“servlet名”+“-servlet.xml”是SPring默认的配置文件命名方式,并存放在WEB-INF目录。如果在初始化时不指定contextConfigLocation,那么Spring默认为WEB-INF的dispatcherServlet-servlet.xml。

(声明:本文部分内容摘译自Rod Johnson, Juergen Hoeller等著的《Spring Reference》一书) 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值