文章目录
前言
Spring Web MVC 是基于Servlet API构建的Web框架,初始Spring框架就包含了该框架。
与其他许多web框架一样,Spring MVC的设计是围绕前置控制器模式其中心是Servlet,DispatcherServlet 为请求处理提供了一个共享算法,而实际工作是由可配置的代理组件执行的,这种模型灵活且执行多种工作流。
DispatcherServlet和任何Servlet一样,需要使用Java配置或web.xml配置,根据Servlet规范进行声明和映射。
反过来说DispatcherServlet使用Spring配置去发现所需要的代理组件,如:请求映射、试图解析、异常处理等。
配置示例
基于Java配置
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
// Load Spring web application configuration
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class);
// Create and register the DispatcherServlet
DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("/app/*");
}
}
基于 Web.xml配置
<web-app><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/app-context.xml</param-value></context-param><servlet><servlet-name>app</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value></param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>app</servlet-name><url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
这两个配置是一样的意思。
DispatcherServlet主要组件
doService方法
- 请求头设置WEB_APPLICATION_CONTEXT(Web应用上下文)
- 请求头设置LOCALE_RESOLVER(本地化解析器)
- 请求头设置THEME_RESOLVER(主题解析器)
- 请求头设置THEME_SOURCE(主题资源)
- 请求头设置OUTPUT_FLASH_MAP(输出FLASH_MAP)
- 请求头设置FLASH_MAP_MANAGER(FLASH_MAP管理)
doDispatch方法
- 判断当前请求是否是MultiPart请求,如果是则通过MultipartResolver将HttpServletRequest解析为MultipartHttpServletRequest。
- 通过List<HandleMapping>,来获取到HandlerExecutionChain,当前对象包含handler(具体执行的对象)和interceptors(在执行时候的拦截器)。
- 通过List<HandlerAdapter>对象,是否支持HandlerExecutionChain对象中的handler的适配,支持则返回HandlerAdapter。
- HandlerExecutionChain执行拦截器前置处理器方法applyPostHandle()。
- 通过HandlerAdapter中的handle执行HandlerExecutionChain中的handle的具体执行。返回ModeAndView(试图)。
- 如果模型和试图不为空,判断是否有默认模型和试图。
- HandlerExecutionChain执行拦截器后置处理器方法applyPostHandle()。
- 执行Dispatch结果方法processDispatchResult,来完成视图的装配工作。
MultipartResolver(多文件解析器)
如果请求需要上传文件,就需要配置MultipartResolver,来完成将HttpServletRequest转换为MultipartHttpServletRequest。
StandardServletMultipartResolver
- 判断请求头Content-Type参数值是否已
multipart/
来判断是否是多文段请求。 - 通过request.getParts(),来解析每一段的内容,如果是文件添加到MultipartFiles中。
- 如果是参数则添加到multipartParameterNames。
CommonsMultipartResolver
- 是借助了Apache Commons FileUpload 组件完成对应文件解析
- 提供了更多的功能:如限制总文件上传大小,限制每个文件上传大小,设置编码等。
- 只支持POST以及求头Content-Type参数值是否存在
multipart/
来判断是否是多文段请求。 - 通过request.getParts(),来解析每一段的内容,如果是文件添加到MultipartFiles中。
- 如果是参数则添加到multipartParameterNames。
LocaleResolver(本地化解析器)
根据用户当前使用的区域设置以及可能的时区,以便能够提供国际化试图。
AbstractLocaleContextResolver(时间区域)
通过使用RequestContext获取用户的时区。getTimeZone()方法。来获得本地化Locale。
实现分别有:
FixedLocaleResolver:只能返回默认设置的Locale和TimeZone。
SessionLocaleResolver:将TimeZone和Locale保存到Session中。
AcceptHeaderLocaleResolver(请求头解析)
通过请求头accept-language
来获取到对应的,不支持时区解析。
CookieLocaleResolver(Cookie解析器)
解析客户端上Cookie,是否设置了Locale或Timezone。如果设置了则使用指定详细信息。
Locale Interceptor(本地化拦截器)
可以通过将LocaleChangeInterceptor添加到HandlerMapping去修改本地化,在检测到请求头参数并修改对应的Locale值。
默认使用:AcceptHeaderLocaleResolver
Themes(主题)
通过使用Spring Web MVC框架中主题来设置应用程序的整体外观,从而增强用户体验。主题是影响应用程序视觉样式的静态资源的集合,通常是样式或图像。
主体必须和主题资源结合在一起使用
。
ResourceBundleThemeSource设置主题资源
styleSheet=/themes/cool/style.css
background=/themes/cool/img/coolBg.jpg
JSP页面使用示例,读取key即可。
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%><html><head><link rel="stylesheet" href="<spring:theme code='styleSheet'/>" type="text/css"/></head><body style="background=<spring:theme code='background'/>">...</body></html>
FixedThemeResolver(固定主题解析)
只能设置默认主题,提供默认主题
SessionThemeResolver(会话主题解析)
主题在用户的HTTP会话中维护,它只需要为每个会话设置一次,但不会在会话之间持久化。
CookieThemeResolver(Cookie主题解析)
主题存储在客户端的Cookie中。
ThemeChangeInterceptor(主题更改拦截器)
通过拦截器允许通过一个简单的请求参数在每个请求上更改主题。
默认使用:FixedThemeResolver
HandlerMapping(处理器映射)
将请求映射到处理程序以及用户预处理和后处理的拦截器列表。映射基于一些标准,这个标准的细节由HandlerMapping具体实现而异。
AbstractHandlerMapping
- 通过
getHandlerInternal
获取对象Handler。 - 如果Handler是字符串,成Bean工厂获取到对象。
- 通过getHandlerExecutionChain获得Handel执行链对象HandlerExecutionChain
- 如果是Cors的则返回Cors校验的执行链。
AbstractUrlHandlerMapping
- 同配置的URL和对象,来获取对象的。
AbstractHandlerMethodMapping
- 根据注解RequestMapping或是Controller生成对应的MappingRegistry。
- 从MappingRegistry获取对应的Handler
RouterFunctionMapping
默认使用
BeanNameUrlHandlerMapping
RequestMappingHandlerMapping
RouterFunctionMapping
HandlerAdapter(处理器适配器)
- 判断当前HandlerAdapter(处理器适配器)是否执行当前的Handler(处理器)
- 如果支持值采用当前适配器,去执行具体的请求。
- 并返回ModeAndView。其值可为空。
HttpRequestHandlerAdapt
- 支持Handler为HttpRequestHandler的适配器
- 具体执行由HttpRequestHandler中handleRequest方法执行
SimpleServletHandlerAdapt
- 支持Handler为Servlet的适配器
- 具体执行由Servlet中service方法执行
HandlerFunctionAdapt
- 支持Handler为HandlerFunction的适配器
- 具体执行由HandlerFunction中handle方法执行
CompositeHandlerAdapt
- 通过代理HandlerAdapter列表,通过具体的HandlerAdapter来判断是否执行
- 通过代理执行具体的方法。
RequestMappingHandlerAdapt
- 支持Handler为HandlerMethod的适配器
- 具体执行由HandlerMethod中ServletInvocableHandlerMethod对象。
- 通过ServletInvocableHandlerMethod中的invokeAndHandle执行具体的方法。
- 一般我们写的请求都是属于这一类。
SimpleControllerHandlerAdapt
- 支持Handler为Controller的适配器
- 具体执行由Controller中handleRequest方法执行
默认使用
HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter
RequestMappingHandlerAdapter
HandlerFunctionAdapter
HandlerExceptionResolver(处理器异常解析器)
HandlerExceptionResolverComposite
- 通过代理对象执行具体的异常解析
CompositeHandlerExceptionResolver
- 通过工厂方法获得所有已创建Bean的HandlerExceptionResolver对象。
- 如果为空则创建:DefaultErrorAttributes和DefaultHandlerExceptionResolver。
- 通过代理执行具体的异常解析。
DefaultErrorAttributes
- 通过将异常数据写入到请求参数中。
SimpleMappingExceptionResolver
- 可以设置排除异常,发生这个异常不返回信息。
- 配置异常类的属性文件
- 如果是在对应的属性异常类中,则返回对应的试图名称。
ExceptionHandlerExceptionResolver
- 根据异常类信息,判断是否有指定异常的方法。如果有则根据异常指定方法返回。
- 如果没有则返回空。
DefaultHandlerExceptionResolver
- 根据异常类名,返回默认的异常ModeAndView。
- 如果异常类不在指定的范围,则返回空。
ResponseStatusExceptionResolver
- 根据如果响应异常状态不为空(只配置了的状态)来返回指定的ModeAndView信息。
- 如果为异常类,则返回ModeAndView(对应异常信息)。
- 都不是返回null。
默认使用
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
RequestToViewNameTranslator(请求视图名称转换)
- 根据传入的名称,返回真正的试图名称。
DefaultRequestToViewNameTranslator
- 设置视图的
前缀
和后缀
。 - 根据配置规范进行转换,在拼接上前缀和后缀。
默认值DefaultRequestToViewNameTranslator
FlashMapManager(FlashMap管理)
SessionFlashMapManager
默认启用:SessionFlashMapManager
ViewResolver(试图解析)
根据viewName(视图名称)和locale(本地化)来获取对应的View。
SessionFlashMapManager
- 通过代理对应的ViewResolver对象,来执行具体的试图解析。
BeanNameViewResolver
- 通过判断viewName(视图名称)是否一个Bean,且Bean的类型为View.class
- 如果是返回对应View,否则返回null。
ContentNegotiatingViewResolver
ResourceBundleViewResolver
XmlViewResolver
UrlBasedViewResolver
TilesViewResolver
ScriptTemplateViewResolver
InternalResourceViewResolver
XsltViewResolver
MustacheViewResolver
GroovyMarkupViewResolver
FreeMarkerViewResolver
默认启用:InternalResourceViewResolver