DispatcherServlet详解
DispatcherServlet
和其它web框架⼀样,Spring的web框架是⼀个请求驱动的web框架,其设计围绕⼀个中⼼的servlet进⾏,它能将请求分发给控制器,并提供其它功能帮助web应⽤开发。然⽽,Spring的DispatcherServlet所做的不仅仅是这些,它和Spring的IoC容器完全集成在⼀起,从⽽允许你使⽤Spring的其它功能。
下图展⽰了DispatcherServlet对请求的处理流程。熟悉设计模式的读者可能会发现DispatcherServlet应⽤了“Front Controller”这个模式(很多其他的主流web框架也都⽤到了这个模式)。
Spring Web MVC处理请求的⼯作流程
DispatcherServlet实际上是⼀个Servlet(它从HttpServlet继承⽽来)。和其它Servlet⼀样,DispatcherServlet定义在web应⽤的l⽂件⾥。DispatcherServlet处理的请求必须在同⼀个l⽂件⾥使⽤url-mapping定义映射。下⾯的例⼦演⽰了如何配置DispatcherServlet。
<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>*.form</url-pattern>
</servlet-mapping>
</web-app>
在上⾯的例⼦⾥,所有以.form结尾的请求都会由名为example的DispatcherServlet处理。这只是配置Spring Web MVC的第⼀步。接下来需要配置DispatcherServlet本⾝和Spring Web MVC 框架⽤到的其他的bean。
正如在中所描述的,Spring中的ApplicationContext可以被限制在不同的作⽤域(scope)中。在web MVC框架中,每个DispatcherServlet有它⾃⼰的WebApplicationContext,这个context继承了根WebApplicationContext的所有bean定义。这些继承的bean也可以在每个serlvet⾃⼰的所属的域中被覆盖(override),覆盖后的bean可以被设置成只有这个servlet实例⾃⼰才可以使⽤的属性。
Spring Web MVC中的Context体系
在DispatcherServlet的初始化过程中,Spring会在web应⽤的WEB-INF⽂件夹下寻名为[servlet-name]-l的配置⽂件,⽣成⽂件中定义的bean。这些bean会覆盖在全局范围(global cope)中
定义的同名的bean。
下⾯这个例⼦展⽰了在l中DispatcherServlet的配置:
<web-app>
...
<servlet>
<servlet-name>golfing</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>golfing</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
要进⾏如上的servlet配置,你还需要配置/l这样⼀个⽂件。l这个⽂件应该声明你在Spring Web MVC 框架中需要的bean。这个⽂件的路径也可以通过l中servlet的初始化参数来更改。(详情见下⾯的例⼦。)
WebApplicationContext仅仅是⼀个拥有web应⽤必要功能的普通ApplicationContext。它与⼀个标准的ApplicationContext的不同之处在于,它能够解析theme(参考),并且它知道⾃⼰与哪个servlet相关联(通过ServletContext)。WebApplicationContext被绑定在ServletContext上,当你需要的时候,可以使⽤RequestContextUtils提供的静态⽅法到WebApplicationContext。
Spring的DispatcherServlet有⼀组特殊的bean,⽤来处理请求和渲染相应的视图。这些bean包含在Spring的框架⾥,可以
在WebApplicationContext中配置,配置⽅式与配置其它bean相同。这些bean中的每⼀个都在下⽂作详细描述。此刻读者只需知道它们的存在,便继续对DispatcherServlet进⾏讨论。对⼤多数bean,Spring
都提供了合理的缺省值,所以在开始阶段,你不必担⼼如何对其进⾏配置。表 13.1. WebApplicationContext中特殊的bean
名称描述
控制器(Controller)实现的是MVC中C那个组成部分。
处理器映射(Handler mapping)包含预处理器(pre-processor),后处理器(post-processor)和控制器的列表,它们在符合某种条件时才被执⾏(例如符合控制器指定的URL)。
视图解析器(View resolvers)可以将视图名解析为对应的视图。
本地化解析器(Locale resolver)能够解析⽤户正在使⽤的本地化设置,以提供国际化视图。
主题解析器(Theme resolver)能够解析你的web应⽤所使⽤的主题,以提供个性化的布局。上传⽂件解析器(multipart file
resolver)提供HTML表单⽂件上传功能。
处理器异常解析器(Handler
exception resolver(s))可以将异常对应到视图,或者实现更加复杂的异常处理代码。
当DispatcherServlet配置好以后,DispatcherServlet接收到与其对应的请求之时,处理就开始了。下⾯的列表描述了DispatcherServlet处理请求的全过程:
1. 到WebApplicationContext并将其绑定到请求的⼀个属性上,以便控制器和处理链上的其它处理器能使⽤WebApplicationContext。默认的属
性名为DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE。
2. 将本地化解析器(localResolver)绑定到请求上,这样使得处理链上的处理器在处理请求(准备数据、显⽰视图等等)时能进⾏本地
化处理。若不使⽤本地化解析器,也不会有任何副作⽤,因此如果不需要本地化解析,忽略它就可以了。
3. 将主题解析器绑定到请求上,这样视图可以决定使⽤哪个主题。如果你不需要主题,可以忽略它。
4. 如果上传⽂件解析器被指定,Spring会检查每个接收到的请求是否存在上传⽂件,如果是,这个请求将被封装
springframework作用成MultipartHttpServletRequest以便被处理链中的其它处理器使⽤。(关于⽂件上传的更多内容请参考。)
5. 到合适的处理器,执⾏和这个处理器相关的执⾏链(预处理器,后处理器,控制器),以便为视图准备模型数据。
6. 如果模型数据被返回,就使⽤配置在WebApplicationContext中的视图解析器显⽰视图,否则视图不会被显⽰。有多种原因可以导致返回的
数据模型为空,⽐如预处理器或后处理器可能截取了请求,这可能是出于安全原因,也可能是请求已经被处理过,没有必要再处理⼀次。
在请求处理过程中抛出的异常,可以被任何定义在WebApplicationContext中的异常解析器所获取。使⽤这些异常解析器,你可以在异常抛出时根据需要定义特定⾏为。
Spring的DispatcherServlet也⽀持返回Servlet API定义的last-modification-date。决定某个请求最后修改的⽇期很简单:DispatcherServlet会⾸先寻⼀个合适的handler mapping,检查从中取得指定的处理器是否实现了LastModified接⼝,如果是,将调⽤long getLastModified(request)⽅法,并将结果返回给客户端。
你可以通过两种⽅式定制Spring的DispatcherServlet:在l⽂件中增加添加context参数,或servlet初始化参数。下⾯是⽬前⽀持的参数。
表 13.2. DispatcherServlet初始化参数
参数描述
contextClass 实现WebApplicationContext接⼝的类,当前的servlet⽤它来创建上下⽂。如果这个参数没有指定,默认使⽤XmlWebApplicationContext。
contextConfigLocation 传给上下⽂实例(由contextClass指定)的字符串,⽤来指定上下⽂的位置。这个字符串可以被分成多个字符串(使⽤逗号作为分隔符)来⽀持多个上下⽂(在多上下⽂的情况下,如果同⼀个bean被定义两次,后⾯⼀个优先)。
namespace WebApplicationContext
命名空间。默认值是[server-name]-servlet。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。