一、解析mvc:default-servlet-handler/

mvc.xml中<mvc:default-servlet-handler/>由DefaultServletHandlerBeanDefinitionParser负责解析。

DefaultServletHandlerBeanDefinitionParser.parse(Element element, ParserContext parserContext)

public BeanDefinition parse(Element element, ParserContext parserContext) {
	Object source = parserContext.extractSource(element);

	String defaultServletName = element.getAttribute("default-servlet-name");
	RootBeanDefinition defaultServletHandlerDef = new RootBeanDefinition(DefaultServletHttpRequestHandler.class);
	defaultServletHandlerDef.setSource(source);
	defaultServletHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	if (StringUtils.hasText(defaultServletName)) {
		defaultServletHandlerDef.getPropertyValues().add("defaultServletName", defaultServletName);
	}
	String defaultServletHandlerName = parserContext.getReaderContext().generateBeanName(defaultServletHandlerDef);
	parserContext.getRegistry().registerBeanDefinition(defaultServletHandlerName, defaultServletHandlerDef);
	parserContext.registerComponent(new BeanComponentDefinition(defaultServletHandlerDef, defaultServletHandlerName));

	Map<String, String> urlMap = new ManagedMap<>();
	urlMap.put("/**", defaultServletHandlerName);

	RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
	handlerMappingDef.setSource(source);
	handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	handlerMappingDef.getPropertyValues().add("urlMap", urlMap);

	String handlerMappingBeanName = parserContext.getReaderContext().generateBeanName(handlerMappingDef);
	parserContext.getRegistry().registerBeanDefinition(handlerMappingBeanName, handlerMappingDef);
	parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, handlerMappingBeanName));

	// Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off"
	MvcNamespaceUtils.registerDefaultComponents(parserContext, source);

	return null;
}

增加DefaultServletHttpRequestHandler的RootBeanDefinition,DefaultServletHttpRequestHandler处理静态文件。增加SimpleUrlHandlerMapping的RootBeanDefinition。SimpleUrlHandlerMapping的urlMap属性增加了/**为key,DefaultServletHttpRequestHandler为value的元素。

二、获取handle
当发起一个没有handle处理方法的请求时,DispatcherServlet.getHandler(HttpServletRequest request)获取对应的handle方法。

DispatcherServlet.getHandler(HttpServletRequest request)

	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
	if (this.handlerMappings != null) {
		for (HandlerMapping mapping : this.handlerMappings) {
			HandlerExecutionChain handler = mapping.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
	}
	return null;
}

handlerMappings中由SimpleUrlHandlerMapping处理Controller类中没有找到处理请求的handle的请求。

AbstractHandlerMapping.getHandler(HttpServletRequest request)

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
	Object handler = getHandlerInternal(request);
	if (handler == null) {
		handler = getDefaultHandler();
	}
	if (handler == null) {
		return null;
	}
	// Bean name or resolved handler?
	if (handler instanceof String) {
		String handlerName = (String) handler;
		handler = obtainApplicationContext().getBean(handlerName);
	}

	// Ensure presence of cached lookupPath for interceptors and others
	if (!ServletRequestPathUtils.hasCachedPath(request)) {
		initLookupPath(request);
	}

	HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

	if (logger.isTraceEnabled()) {
		logger.trace("Mapped to " + handler);
	}
	else if (logger.isDebugEnabled() && !DispatcherType.ASYNC.equals(request.getDispatcherType())) {
		logger.debug("Mapped to " + executionChain.getHandler());
	}

	if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
		CorsConfiguration config = getCorsConfiguration(handler, request);
		if (getCorsConfigurationSource() != null) {
			CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);
			config = (globalConfig != null ? globalConfig.combine(config) : config);
		}
		if (config != null) {
			config.validateAllowCredentials();
		}
		executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
	}

	return executionChain;
}

1、getHandlerInternal获取handle,若不能获取getDefaultHandler获取默认的handle,还是不能获取handle返回null。
2、如果获取到了handle,调用getHandlerExecutionChain获取handle执行链
3、处理CORS

AbstractUrlHandlerMapping.getHandlerInternal(HttpServletRequest request)

protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
	String lookupPath = initLookupPath(request);
	Object handler;
	if (usesPathPatterns()) {
		RequestPath path = ServletRequestPathUtils.getParsedRequestPath(request);
		handler = lookupHandler(path, lookupPath, request);
	}
	else {
		handler = lookupHandler(lookupPath, request);
	}
	if (handler == null) {
		// We need to care for the default handler directly, since we need to
		// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
		Object rawHandler = null;
		if (StringUtils.matchesCharacter(lookupPath, '/')) {
			rawHandler = getRootHandler();
		}
		if (rawHandler == null) {
			rawHandler = getDefaultHandler();
		}
		if (rawHandler != null) {
			// Bean name or resolved handler?
			if (rawHandler instanceof String) {
				String handlerName = (String) rawHandler;
				rawHandler = obtainApplicationContext().getBean(handlerName);
			}
			validateHandler(rawHandler, request);
			handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
		}
	}
	return handler;
}

1、initLookupPath获取请求路径
2、lookupHandler获取handle
3、获取不到handle则获取默认handle

AbstractUrlHandlerMapping.lookupHandler(String lookupPath, HttpServletRequest request)

protected Object lookupHandler(String lookupPath, HttpServletRequest request) throws Exception {
Object handler = getDirectMatch(lookupPath, request);
if (handler != null) {
return handler;
}

	// Pattern match?
	List<String> matchingPatterns = new ArrayList<>();
	for (String registeredPattern : this.handlerMap.keySet()) {
		if (getPathMatcher().match(registeredPattern, lookupPath)) {
			matchingPatterns.add(registeredPattern);
		}
		else if (useTrailingSlashMatch()) {
			if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", lookupPath)) {
				matchingPatterns.add(registeredPattern + "/");
			}
		}
	}

	String bestMatch = null;
	Comparator<String> patternComparator = getPathMatcher().getPatternComparator(lookupPath);
	if (!matchingPatterns.isEmpty()) {
		matchingPatterns.sort(patternComparator);
		if (logger.isTraceEnabled() && matchingPatterns.size() > 1) {
			logger.trace("Matching patterns " + matchingPatterns);
		}
		bestMatch = matchingPatterns.get(0);
	}
	if (bestMatch != null) {
		handler = this.handlerMap.get(bestMatch);
		if (handler == null) {
			if (bestMatch.endsWith("/")) {
				handler = this.handlerMap.get(bestMatch.substring(0, bestMatch.length() - 1));
			}
			if (handler == null) {
				throw new IllegalStateException(
						"Could not find handler for best pattern match [" + bestMatch + "]");
			}
		}
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = obtainApplicationContext().getBean(handlerName);
		}
		validateHandler(handler, request);
		String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestMatch, lookupPath);

		// There might be multiple 'best patterns', let's make sure we have the correct URI template variables
		// for all of them
		Map<String, String> uriTemplateVariables = new LinkedHashMap<>();
		for (String matchingPattern : matchingPatterns) {
			if (patternComparator.compare(bestMatch, matchingPattern) == 0) {
				Map<String, String> vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, lookupPath);
				Map<String, String> decodedVars = getUrlPathHelper().decodePathVariables(request, vars);
				uriTemplateVariables.putAll(decodedVars);
			}
		}
		if (logger.isTraceEnabled() && uriTemplateVariables.size() > 0) {
			logger.trace("URI variables " + uriTemplateVariables);
		}
		return buildPathExposingHandler(handler, bestMatch, pathWithinMapping, uriTemplateVariables);
	}

	// No handler found...
	return null;
}

1、getDirectMatch通过请求路径完全匹配获取handle
2、如果获取不到handle,遍历handlerMap,将handlerMap中的所有registeredPattern和请求路径进行模式匹配。如匹配则加入matchingPatterns。
3、如果存在模式匹配则从handlerMap获取handle。
4、extractPathWithinPattern从路径模式和请求路径中解析出模式映射部分。如模式为myroot/*.html,请求路径是myroot/myfile.html,返回myfile.html
5、extractUriTemplateVariables解析uri模板变量
6、buildPathExposingHandler构建暴露的handle

AbstractUrlHandlerMapping.getDirectMatch(String urlPath, HttpServletRequest request)

private Object getDirectMatch(String urlPath, HttpServletRequest request) throws Exception {
	Object handler = this.handlerMap.get(urlPath);
	if (handler != null) {
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = obtainApplicationContext().getBean(handlerName);
		}
		validateHandler(handler, request);
		return buildPathExposingHandler(handler, urlPath, urlPath, null);
	}
	return null;
}

从handlerMap中通过请求路径完全匹配获取handle,如果获取到了则调用getBean获取对应的bean。handlerMap中的key为/**,value为DefaultServletHttpRequestHandler。

AbstractUrlHandlerMapping.buildPathExposingHandler(Object rawHandler, String bestMatchingPattern,
String pathWithinMapping, @Nullable Map<String, String> uriTemplateVariables)

protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern,
		String pathWithinMapping, @Nullable Map<String, String> uriTemplateVariables) {

	HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);
	chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping));
	if (!CollectionUtils.isEmpty(uriTemplateVariables)) {
		chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables));
	}
	return chain;
}

1、创建HandlerExecutionChain
2、HandlerExecutionChain中加入PathExposingHandlerInterceptor
3、如果存在uri模板变量则往HandlerExecutionChain加入UriTemplateVariablesHandlerInterceptor

AbstractHandlerMapping.getHandlerExecutionChain(Object handler, HttpServletRequest request)

  	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
	HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
			(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

	for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
		if (interceptor instanceof MappedInterceptor) {
			MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
			if (mappedInterceptor.matches(request)) {
				chain.addInterceptor(mappedInterceptor.getInterceptor());
			}
		}
		else {
			chain.addInterceptor(interceptor);
		}
	}
	return chain;
}

获取HandlerExecutionChain。HandlerExecutionChain中保存了所有的请求拦截器。

三、处理请求

DispatcherServlet.getHandlerAdapter(Object handler)

	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
	if (this.handlerAdapters != null) {
		for (HandlerAdapter adapter : this.handlerAdapters) {
			if (adapter.supports(handler)) {
				return adapter;
			}
		}
	}
	throw new ServletException("No adapter for handler [" + handler +
			"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}

通过handle获取HandlerAdapter。handle是DefaultServletHttpRequestHandler。HttpRequestHandlerAdapter处理DefaultServletHttpRequestHandler类型的handle。返回HttpRequestHandlerAdapter。

HttpRequestHandlerAdapter.handle(HttpServletRequest request, HttpServletResponse response, Object handler)

public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception {

	((HttpRequestHandler) handler).handleRequest(request, response);
	return null;
}

DefaultServletHttpRequestHandler.handleRequest(HttpServletRequest request, HttpServletResponse response)

	public void handleRequest(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {

	Assert.state(this.servletContext != null, "No ServletContext set");
	RequestDispatcher rd = this.servletContext.getNamedDispatcher(this.defaultServletName);
	if (rd == null) {
		throw new IllegalStateException("A RequestDispatcher could not be located for the default servlet '" +
				this.defaultServletName + "'");
	}
	rd.forward(request, response);
}

获取RequestDispatcher,forward转发请求。

没有handle处理的请求的状态码是404,如果没有配置对应的处理页面。则由web容器处理。tomcat处理页面时

如果在web.xml中配置

<error-page>
	<error-code>404</error-code>
	<location>/404</location>
</error-page>

对应状态码的处理请求。则上面的DefaultServletHttpRequestHandler.handleRequest会在当前请求转发一个请求。请求路径是上面配置的location。

例如:

	@RequestMapping("/404")
public String handleNoFound() {
	return "404";
}

由这个handle处理404状态码的请求。

原文地址:http://www.cnblogs.com/shigongp/p/16905583.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性