- 浏览: 4783 次
- 性别:
- 来自: 北京
最新评论
1、Dispatcher中的属性:
/** Well-known name for the MultipartResolver object in the bean factory for this namespace. */
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
/** Well-known name for the LocaleResolver object in the bean factory for this namespace. */
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
/** Well-known name for the ThemeResolver object in the bean factory for this namespace. */
public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
/**
* Well-known name for the HandlerMapping object in the bean factory for this namespace.
* Only used when "detectAllHandlerMappings" is turned off.
* @see #setDetectAllHandlerMappings
*/
public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
/**
* Well-known name for the HandlerAdapter object in the bean factory for this namespace.
* Only used when "detectAllHandlerAdapters" is turned off.
* @see #setDetectAllHandlerAdapters
*/
public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
/**
* Well-known name for the HandlerExceptionResolver object in the bean factory for this namespace.
* Only used when "detectAllHandlerExceptionResolvers" is turned off.
* @see #setDetectAllHandlerExceptionResolvers
*/
public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
/**
* Well-known name for the RequestToViewNameTranslator object in the bean factory for this namespace.
*/
public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
/**
* Well-known name for the ViewResolver object in the bean factory for this namespace.
* Only used when "detectAllViewResolvers" is turned off.
* @see #setDetectAllViewResolvers
*/
public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
/**
* Well-known name for the FlashMapManager object in the bean factory for this namespace.
*/
public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
/**
* Request attribute to hold the current web application context.
* Otherwise only the global web app context is obtainable by tags etc.
* @see org.springframework.web.servlet.support.RequestContextUtils#getWebApplicationContext
*/
public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";
/**
* Request attribute to hold the current LocaleResolver, retrievable by views.
* @see org.springframework.web.servlet.support.RequestContextUtils#getLocaleResolver
*/
public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER";
/**
* Request attribute to hold the current ThemeResolver, retrievable by views.
* @see org.springframework.web.servlet.support.RequestContextUtils#getThemeResolver
*/
public static final String THEME_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_RESOLVER";
/**
* Request attribute to hold the current ThemeSource, retrievable by views.
* @see org.springframework.web.servlet.support.RequestContextUtils#getThemeSource
*/
public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE";
/**
* Name of request attribute that holds a read-only {@code Map<String,?>}
* with "input" flash attributes saved by a previous request, if any.
* @see org.springframework.web.servlet.support.RequestContextUtils#getInputFlashMap(HttpServletRequest)
*/
public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP";
/**
* Name of request attribute that holds the "output" {@link FlashMap} with
* attributes to save for a subsequent request.
* @see org.springframework.web.servlet.support.RequestContextUtils#getOutputFlashMap(HttpServletRequest)
*/
public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP";
/**
* Name of request attribute that holds the {@link FlashMapManager}.
* @see org.springframework.web.servlet.support.RequestContextUtils#getFlashMapManager(HttpServletRequest)
*/
public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER";
/** Log category to use when no mapped handler is found for a request. */
public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";
/**
* Name of the class path resource (relative to the DispatcherServlet class)
* that defines DispatcherServlet's default strategy names.
*/
private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";
/** Additional logger to use when no mapped handler is found for a request. */
protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY);
private static final UrlPathHelper urlPathHelper = new UrlPathHelper();
private static final Properties defaultStrategies;
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
}
}
/** Detect all HandlerMappings or just expect "handlerMapping" bean? */
private boolean detectAllHandlerMappings = true;
/** Detect all HandlerAdapters or just expect "handlerAdapter" bean? */
private boolean detectAllHandlerAdapters = true;
/** Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean? */
private boolean detectAllHandlerExceptionResolvers = true;
/** Detect all ViewResolvers or just expect "viewResolver" bean? */
private boolean detectAllViewResolvers = true;
/** Perform cleanup of request attributes after include request? */
private boolean cleanupAfterInclude = true;
/** MultipartResolver used by this servlet */
private MultipartResolver multipartResolver;
/** LocaleResolver used by this servlet */
private LocaleResolver localeResolver;
/** ThemeResolver used by this servlet */
private ThemeResolver themeResolver;
/** List of HandlerMappings used by this servlet */
private List<HandlerMapping> handlerMappings;
/** List of HandlerAdapters used by this servlet */
private List<HandlerAdapter> handlerAdapters;
/** List of HandlerExceptionResolvers used by this servlet */
private List<HandlerExceptionResolver> handlerExceptionResolvers;
/** RequestToViewNameTranslator used by this servlet */
private RequestToViewNameTranslator viewNameTranslator;
/** FlashMapManager used by this servlet */
private FlashMapManager flashMapManager;
/** List of ViewResolvers used by this servlet */
private List<ViewResolver> viewResolvers;
2、DispatcherServlet中的方法(get/set方法不列)
(上传图片这么麻烦?不能直接粘贴图片?此处省略)
3、DispatcherServlet中的静态块代码如下
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
}
}
该静态块在DispatcherServlet在初始化或第一次调用时执行,一般用来加载配置文件,DispatcherServlets使用该静态块加载配置文件;
使用上DispatcherServlet中的属性private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";阅读静态块代码可调用了SpringMVC中的抽象类
PropertiesLoaderUtils中的loadProperties方法加载读取配置文件'DispatcherServlet.properties'.
'DispatcherServlet.properties'的配置文件如下:
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
1、Controller:处理器/页面控制器,做的是MVC中的C的事情,但控制逻辑转移到前端控制器了,用于对请求进行处理;
2、HandlerMapping:请求到处理器的映射,如果映射成功返回一个HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象;如BeanNameUrlHandlerMapping将URL与Bean名字映射,映射成功的Bean就是此处的处理器;
3、HandlerAdapter:HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;如SimpleControllerHandlerAdapter将对实现了Controller接口的Bean进行适配,并且掉处理器的handleRequest方法进行功能处理;
4、ViewResolver:ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;如InternalResourceViewResolver将逻辑视图名映射为jsp视图;
5、LocalResover:本地化解析,因为Spring支持国际化,因此LocalResover解析客户端的Locale信息从而方便进行国际化;
6、ThemeResovler:主题解析,通过它来实现一个页面多套风格,即常见的类似于软件皮肤效果;
7、MultipartResolver:文件上传解析,用于支持文件上传;
8、HandlerExceptionResolver:处理器异常解析,可以将异常映射到相应的统一错误界面,从而显示用户友好的界面(而不是给用户看到具体的错误信息);
9、RequestToViewNameTranslator:当处理器没有返回逻辑视图名等相关信息时,自动将请求URL映射为逻辑视图名;
10、FlashMapManager:用于管理FlashMap的策略接口,FlashMap用于存储一个请求的输出,当进入另一个请求时作为该请求的输入,通常用于重定向场景,后边会细述。
主要是用来设置SpringMVC框架中定义接口的默认实现类
DispatcherServlet类调用的入口方法为doService,代码如下:
/**
* Exposes the DispatcherServlet-specific request attributes and delegates to {@link #doDispatch}
* for the actual dispatching.
*/
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
" processing " + request.getMethod() + " request for [" + requestUri + "]");
}
// Keep a snapshot of the request attributes in case of an include,
// 创建请求属性快照,以便恢复属性
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
logger.debug("Taking snapshot of request attributes before include");
attributesSnapshot = new HashMap<String, Object>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
// Make framework objects available to handlers and view objects.将请求与框架处理对象进行绑定
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
//SpringMVC3.1引入对象,当post提交数据之后,按F5刷新界面时,会发生重复提交,之后,为了不解决重复提交问题,需要在post提交数据之后
//使用Redirect进行重定向,但是,将会丢失数据,为了解决这一问题,在request中加入一属性,就是FlashMap,FlashMap数据是和request绑定
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
try {
//转入doDispatch方法
doDispatch(request, response);
}
finally {
if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
return;
}
//恢复原来的属性
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
DispatcherServlet类核心方法,也是SpringMVC的核心,代码如下
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
//获取当前请求的异步处理对象WebAsyncManager,如果不存在,则创建一个异步请求对象关联该请求,异步处理返回结果在一个线程
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
//定义ModelAndView对象,对象包含属性model/view/cleared(默认属性为flash)
ModelAndView mv = null;
//异常对象
Exception dispatchException = null;
try {
//对请求中的上传文件进行处理
processedRequest = checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// 确定当前请求的处理器/返回值为HandlerExcutionChain(请求执行链)
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// 确定当前请求处理程序适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 如果处理器支持,在最后修改请求head信息
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
try {
//调用处理器处理请求.并将返回处理过程中,创建的ModelAndVIew
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
//设置返回视图名称
applyDefaultViewName(request, mv);
//执行拦截器中的afterCompletion方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
//对ModelAndView进行检测处理
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Error err) {
triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
return;
}
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
总结:DispatcherServlet类的运行流程如下:
doService-doDispatch(
1、检查请求类型,是否包含上传文件,如果存在,则使用上传文件进行处理,并将request进行封装返回
2、获取HandlerExcutionChain执行链,通过调用HandlerMapping实现类,获取HandlerExcutionChain,HandlerExcutionChain包括Handler对象、拦截器组、拦截器集合
3、获取handlerAdapter确定请求处理器,通过getHandler方法获取handlerAdapter对象
4、调用处理器处理请求.并在处理方法中,创建的ModelAndVIew
5、从ModelAndView对象中获取响应界面,设置返回视图名称applyDefaultViewName(request, mv);
6、对返回的ModelAndView进行检测
)
/** Well-known name for the MultipartResolver object in the bean factory for this namespace. */
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
/** Well-known name for the LocaleResolver object in the bean factory for this namespace. */
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
/** Well-known name for the ThemeResolver object in the bean factory for this namespace. */
public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
/**
* Well-known name for the HandlerMapping object in the bean factory for this namespace.
* Only used when "detectAllHandlerMappings" is turned off.
* @see #setDetectAllHandlerMappings
*/
public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
/**
* Well-known name for the HandlerAdapter object in the bean factory for this namespace.
* Only used when "detectAllHandlerAdapters" is turned off.
* @see #setDetectAllHandlerAdapters
*/
public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
/**
* Well-known name for the HandlerExceptionResolver object in the bean factory for this namespace.
* Only used when "detectAllHandlerExceptionResolvers" is turned off.
* @see #setDetectAllHandlerExceptionResolvers
*/
public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
/**
* Well-known name for the RequestToViewNameTranslator object in the bean factory for this namespace.
*/
public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
/**
* Well-known name for the ViewResolver object in the bean factory for this namespace.
* Only used when "detectAllViewResolvers" is turned off.
* @see #setDetectAllViewResolvers
*/
public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
/**
* Well-known name for the FlashMapManager object in the bean factory for this namespace.
*/
public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
/**
* Request attribute to hold the current web application context.
* Otherwise only the global web app context is obtainable by tags etc.
* @see org.springframework.web.servlet.support.RequestContextUtils#getWebApplicationContext
*/
public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";
/**
* Request attribute to hold the current LocaleResolver, retrievable by views.
* @see org.springframework.web.servlet.support.RequestContextUtils#getLocaleResolver
*/
public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER";
/**
* Request attribute to hold the current ThemeResolver, retrievable by views.
* @see org.springframework.web.servlet.support.RequestContextUtils#getThemeResolver
*/
public static final String THEME_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_RESOLVER";
/**
* Request attribute to hold the current ThemeSource, retrievable by views.
* @see org.springframework.web.servlet.support.RequestContextUtils#getThemeSource
*/
public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE";
/**
* Name of request attribute that holds a read-only {@code Map<String,?>}
* with "input" flash attributes saved by a previous request, if any.
* @see org.springframework.web.servlet.support.RequestContextUtils#getInputFlashMap(HttpServletRequest)
*/
public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP";
/**
* Name of request attribute that holds the "output" {@link FlashMap} with
* attributes to save for a subsequent request.
* @see org.springframework.web.servlet.support.RequestContextUtils#getOutputFlashMap(HttpServletRequest)
*/
public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP";
/**
* Name of request attribute that holds the {@link FlashMapManager}.
* @see org.springframework.web.servlet.support.RequestContextUtils#getFlashMapManager(HttpServletRequest)
*/
public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER";
/** Log category to use when no mapped handler is found for a request. */
public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";
/**
* Name of the class path resource (relative to the DispatcherServlet class)
* that defines DispatcherServlet's default strategy names.
*/
private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";
/** Additional logger to use when no mapped handler is found for a request. */
protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY);
private static final UrlPathHelper urlPathHelper = new UrlPathHelper();
private static final Properties defaultStrategies;
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
}
}
/** Detect all HandlerMappings or just expect "handlerMapping" bean? */
private boolean detectAllHandlerMappings = true;
/** Detect all HandlerAdapters or just expect "handlerAdapter" bean? */
private boolean detectAllHandlerAdapters = true;
/** Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean? */
private boolean detectAllHandlerExceptionResolvers = true;
/** Detect all ViewResolvers or just expect "viewResolver" bean? */
private boolean detectAllViewResolvers = true;
/** Perform cleanup of request attributes after include request? */
private boolean cleanupAfterInclude = true;
/** MultipartResolver used by this servlet */
private MultipartResolver multipartResolver;
/** LocaleResolver used by this servlet */
private LocaleResolver localeResolver;
/** ThemeResolver used by this servlet */
private ThemeResolver themeResolver;
/** List of HandlerMappings used by this servlet */
private List<HandlerMapping> handlerMappings;
/** List of HandlerAdapters used by this servlet */
private List<HandlerAdapter> handlerAdapters;
/** List of HandlerExceptionResolvers used by this servlet */
private List<HandlerExceptionResolver> handlerExceptionResolvers;
/** RequestToViewNameTranslator used by this servlet */
private RequestToViewNameTranslator viewNameTranslator;
/** FlashMapManager used by this servlet */
private FlashMapManager flashMapManager;
/** List of ViewResolvers used by this servlet */
private List<ViewResolver> viewResolvers;
2、DispatcherServlet中的方法(get/set方法不列)
(上传图片这么麻烦?不能直接粘贴图片?此处省略)
3、DispatcherServlet中的静态块代码如下
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
}
}
该静态块在DispatcherServlet在初始化或第一次调用时执行,一般用来加载配置文件,DispatcherServlets使用该静态块加载配置文件;
使用上DispatcherServlet中的属性private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";阅读静态块代码可调用了SpringMVC中的抽象类
PropertiesLoaderUtils中的loadProperties方法加载读取配置文件'DispatcherServlet.properties'.
'DispatcherServlet.properties'的配置文件如下:
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
1、Controller:处理器/页面控制器,做的是MVC中的C的事情,但控制逻辑转移到前端控制器了,用于对请求进行处理;
2、HandlerMapping:请求到处理器的映射,如果映射成功返回一个HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象;如BeanNameUrlHandlerMapping将URL与Bean名字映射,映射成功的Bean就是此处的处理器;
3、HandlerAdapter:HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;如SimpleControllerHandlerAdapter将对实现了Controller接口的Bean进行适配,并且掉处理器的handleRequest方法进行功能处理;
4、ViewResolver:ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;如InternalResourceViewResolver将逻辑视图名映射为jsp视图;
5、LocalResover:本地化解析,因为Spring支持国际化,因此LocalResover解析客户端的Locale信息从而方便进行国际化;
6、ThemeResovler:主题解析,通过它来实现一个页面多套风格,即常见的类似于软件皮肤效果;
7、MultipartResolver:文件上传解析,用于支持文件上传;
8、HandlerExceptionResolver:处理器异常解析,可以将异常映射到相应的统一错误界面,从而显示用户友好的界面(而不是给用户看到具体的错误信息);
9、RequestToViewNameTranslator:当处理器没有返回逻辑视图名等相关信息时,自动将请求URL映射为逻辑视图名;
10、FlashMapManager:用于管理FlashMap的策略接口,FlashMap用于存储一个请求的输出,当进入另一个请求时作为该请求的输入,通常用于重定向场景,后边会细述。
主要是用来设置SpringMVC框架中定义接口的默认实现类
DispatcherServlet类调用的入口方法为doService,代码如下:
/**
* Exposes the DispatcherServlet-specific request attributes and delegates to {@link #doDispatch}
* for the actual dispatching.
*/
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
" processing " + request.getMethod() + " request for [" + requestUri + "]");
}
// Keep a snapshot of the request attributes in case of an include,
// 创建请求属性快照,以便恢复属性
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
logger.debug("Taking snapshot of request attributes before include");
attributesSnapshot = new HashMap<String, Object>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
// Make framework objects available to handlers and view objects.将请求与框架处理对象进行绑定
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
//SpringMVC3.1引入对象,当post提交数据之后,按F5刷新界面时,会发生重复提交,之后,为了不解决重复提交问题,需要在post提交数据之后
//使用Redirect进行重定向,但是,将会丢失数据,为了解决这一问题,在request中加入一属性,就是FlashMap,FlashMap数据是和request绑定
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
try {
//转入doDispatch方法
doDispatch(request, response);
}
finally {
if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
return;
}
//恢复原来的属性
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
DispatcherServlet类核心方法,也是SpringMVC的核心,代码如下
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
//获取当前请求的异步处理对象WebAsyncManager,如果不存在,则创建一个异步请求对象关联该请求,异步处理返回结果在一个线程
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
//定义ModelAndView对象,对象包含属性model/view/cleared(默认属性为flash)
ModelAndView mv = null;
//异常对象
Exception dispatchException = null;
try {
//对请求中的上传文件进行处理
processedRequest = checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// 确定当前请求的处理器/返回值为HandlerExcutionChain(请求执行链)
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// 确定当前请求处理程序适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 如果处理器支持,在最后修改请求head信息
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
try {
//调用处理器处理请求.并将返回处理过程中,创建的ModelAndVIew
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
//设置返回视图名称
applyDefaultViewName(request, mv);
//执行拦截器中的afterCompletion方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
//对ModelAndView进行检测处理
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Error err) {
triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
return;
}
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
总结:DispatcherServlet类的运行流程如下:
doService-doDispatch(
1、检查请求类型,是否包含上传文件,如果存在,则使用上传文件进行处理,并将request进行封装返回
2、获取HandlerExcutionChain执行链,通过调用HandlerMapping实现类,获取HandlerExcutionChain,HandlerExcutionChain包括Handler对象、拦截器组、拦截器集合
3、获取handlerAdapter确定请求处理器,通过getHandler方法获取handlerAdapter对象
4、调用处理器处理请求.并在处理方法中,创建的ModelAndVIew
5、从ModelAndView对象中获取响应界面,设置返回视图名称applyDefaultViewName(request, mv);
6、对返回的ModelAndView进行检测
)
相关推荐
SpringMVC 的执行流程是理解其工作原理的关键,下面我们将详细解析这个过程。 首先,SpringMVC 的执行流程始于客户端发起的HTTP请求,这个请求被Web服务器接收到。在传统的Java Web应用中,Web服务器(如Tomcat)会...
### Spring MVC 执行流程详解 #### 一、概述 Spring MVC 是 Spring 框架中的一个重要组成部分,主要用于构建基于 Web 的应用程序。它提供了一个清晰的架构来管理 Web 层的业务逻辑,使得开发者能够轻松地处理 ...
DispatcherServlet的工作流程包括以下步骤: 1. 拦截请求:DispatcherServlet作为所有HTTP请求的入口点。 2. 请求映射:根据请求URL和请求方法匹配到合适的HandlerMapping。 3. 视图解析:处理器执行完成后,返回一...
在本文中,我们将深入探讨`DispatcherServlet`的初始化流程,这是SpringMVC的核心组件。`DispatcherServlet`扮演着中央调度者的角色,负责接收请求、解析请求信息,并调用合适的控制器进行业务逻辑处理。 首先,让...
理解DispatcherServlet的工作流程,对于深入掌握Spring MVC框架至关重要。在实际开发中,我们可以根据需求自定义HandlerMapping和HandlerAdapter,以满足特定的应用场景,实现更加定制化的请求处理。
总结来说,SpringMVC 的执行流程主要包括:DispatcherServlet 的调度、HandlerMapping 的映射、HandlerAdapter 的适配、数据处理、Handler 的执行、ModelAndView 的返回、ViewResolver 的解析以及视图的渲染。...
SpringMVC底层执行流程及原理解析 SpringMVC作为Java开发中的一个重要框架,了解其底层执行流程及原理是非常重要的。本文将通过示例代码详细介绍SpringMVC底层执行流程及原理,并对其进行深入分析。 一、...
分类专栏: java框架 文章标签: spring mvc spring mybatis 作用: SSM框架是spring MVC ,... springMVC执行流程: 1. 客户端将请求统一提交到DispatcherServlet; 2. DispatcherServlet会将请求交给HandlerMapping
本篇文章将深入探讨DispatcherServlet的请求分发流程。 DispatcherServlet继承自HttpServlet,其核心功能在于处理HTTP请求。在Servlet的service方法中,DispatcherServlet会接收到请求并进行分发。在...
SpringMVC的执行流程及组件详解 SpringMVC是一个基于Java的Web应用程序框架,它提供了一种灵活的方式来构建Web应用程序。理解SpringMVC的执行流程及组件是开发高质量Web应用程序的关键。本文将对SpringMVC的执行...
总结,SpringMVC的处置流程始于Web应用的初始化,包括ContextLoaderListener加载根上下文和DispatcherServlet初始化子上下文。接着,DispatcherServlet负责接收和分发请求,通过HandlerMapping找到处理器,...
DispatcherServlet 是整个流程的入口点,它负责拦截所有请求并根据配置进行转发。DispatcherServlet 首先会解析请求,然后寻找合适的 HandlerMapping 对象来确定哪个控制器(Controller)应该处理该请求。 2. **...
#### 二、Spring MVC 执行流程 ##### 1. DispatcherServlet 初始化 - **启动过程**:当应用程序启动时,Web 服务器会加载配置好的 Servlet 容器并实例化配置的 Servlet。在 Spring MVC 中,这个 Servlet 就是 `...
一旦找到,处理器映射器会将找到的处理器信息(通常包括处理器类和方法等)返回给`DispatcherServlet`。 3. **处理器适配器(Handler Adapter)**:`DispatcherServlet`接下来会使用处理器适配器去调用之前找到的...
这个方法是整个请求处理流程的起点。在`processRequest()`内部,Spring MVC开始执行一系列步骤,包括: 1. 记录请求开始时间,用于性能监控。 2. 设置当前请求的`LocaleResolver`和`LocaleContext`,以处理国际化...
preHandle方法在处理器执行之前调用,postHandle在处理器执行后调用,afterCompletion在DispatcherServlet渲染视图之后调用。 - 在HandlerMapping的实现类中,例如RequestMappingHandlerMapping,会通过反射机制来...
下面我们将详细探讨SpringMVC的执行流程及其关键组件。 1. **前端控制器(DispatcherServlet)**:所有HTTP请求首先会被DispatcherServlet捕获。它是SpringMVC的入口点,负责调度整个流程。DispatcherServlet解析...
首先,SpringMVC的执行流程始于客户端发起HTTP请求。这个请求被DispatcherServlet(前置控制器)拦截,它是整个SpringMVC框架的核心,负责接收和分发请求。DispatcherServlet根据请求URL来确定控制器(Controller)...
DispatcherServlet是整个流程的核心,负责调度请求到相应的处理器。 3. **映射器查找**:DispatcherServlet会查询一系列的HandlerMapping(处理器映射器)来确定哪个控制器应该处理请求。处理器映射器根据URL、注解...
DispatcherServlet是整个流程的中心,它负责调度和协调其他组件。它就像一个交通指挥员,接收所有请求,并决定这些请求应该如何被处理。 第二步,DispatcherServlet会查询HandlerMapping,这是一个负责将请求映射到...