SpringMVC 源码之网络请求(2)

DispatcherServlet#checkMultipart

定位: org.springframework.web.servlet.DispatcherServlet#checkMultipart

检测请求是否为上传请求,如果是则通过 multipartResolver 将其封装成 MultipartHttpServletRequest 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
// 如果该请求是一个涉及到 multipart (文件)的请求
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
if (request.getDispatcherType().equals(DispatcherType.REQUEST)) {
logger.trace("Request already resolved to MultipartHttpServletRequest, e.g. by MultipartFilter");
}
}
else if (hasMultipartException(request)) {
logger.debug("Multipart resolution previously failed for current request - " +
"skipping re-resolution for undisturbed error rendering");
}
else {
try {
// 将 HttpServletRequest 请求封装成 MultipartHttpServletRequest 对象,解析请求里面的参数以及文件
return this.multipartResolver.resolveMultipart(request);
}
catch (MultipartException ex) {
if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) {
logger.debug("Multipart resolution failed for error dispatch", ex);
// Keep processing error dispatch with regular request handle below
}
else {
throw ex;
}
}
}
}
// If not returned before: return original request.
return request;
}

DispatcherServlet#getHandler

定位: org.springframework.web.servlet.DispatcherServlet#getHandler
定位: org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 获得处理器(HandlerMethod或者HandlerExecutionChain),该方法是抽象方法,由子类实现
Object handler = getHandlerInternal(request);
// 获得不到,则使用默认处理器
if (handler == null) {
handler = getDefaultHandler();
}
// 还是获得不到,则返回 null
if (handler == null) {
return null;
}
// Bean name or resolved handler?
// 如果找到的处理器是String类型,则从Spring容器中找到对应的Bean作为处理器
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}

// 创建HandlerExecutionChain对象(包含处理器和拦截器)
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

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

// 针对跨域请求的处理
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}

return executionChain;
}

org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal

RequestMappingHandlerMapping 实现了 AbstractHandlerMethodMapping
RequestMappingHandlerMapping 处理添加 @RequestMapping 的 API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 获取访问的路径,一般类似于request.getServletPath(),返回不含contextPath的访问路径
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
request.setAttribute(LOOKUP_PATH, lookupPath);
// 获得读锁
this.mappingRegistry.acquireReadLock();
try {
// 获取HandlerMethod作为handler对象,这里涉及到路径匹配的优先级
// 优先级: 精确匹配>最长路径匹配>扩展名匹配
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
// handlerMethod内部包含有bean对象,其实指的是对应的controller
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
// 释放读锁
this.mappingRegistry.releaseReadLock();
}
}

org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#lookupHandlerMethod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
// Match数组,存储匹配上当前请求的结果(Mapping + HandlerMethod)
List<Match> matches = new ArrayList<>();
// 首先根据lookupPath获取到匹配条件
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
if (directPathMatches != null) {
// 将找到的匹配条件添加到matches
addMatchingMappings(directPathMatches, matches, request);
}
// 如果不能直接使用lookupPath得到匹配条件,则将所有匹配条件加入matches
if (matches.isEmpty()) {
// No choice but to go through all mappings...
addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
}

// 将包含匹配条件和handler的matches排序,并取第一个作为bestMatch,如果前面两个排序相同则抛出异常
if (!matches.isEmpty()) {
Match bestMatch = matches.get(0);
if (matches.size() > 1) {
// 创建MatchComparator对象,排序matches结果,排序器
Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
matches.sort(comparator);
// 获得首个Match对象,也就是最匹配的
bestMatch = matches.get(0);
if (logger.isTraceEnabled()) {
logger.trace(matches.size() + " matching mappings: " + matches);
}
if (CorsUtils.isPreFlightRequest(request)) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
// 比较bestMatch和secondBestMatch,如果相等,说明有问题,抛出IllegalStateException异常
// 因为,两个优先级一样高,说明无法判断谁更优先
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.handlerMethod.getMethod();
Method m2 = secondBestMatch.handlerMethod.getMethod();
String uri = request.getRequestURI();
throw new IllegalStateException(
"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
}
}
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
// 处理首个Match对象
handleMatch(bestMatch.mapping, lookupPath, request);
// 返回首个Match对象的handlerMethod属性
return bestMatch.handlerMethod;
}
// 如果匹配不到,则处理不匹配的情况
else {
return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
}
}

org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#getHandlerInternal

BeanNameUrlHandlerMapping 和 SimpleUrlHandlerMapping 实现了 AbstractUrlHandlerMapping
BeanNameUrlHandlerMapping 处理容器 bean 对象的名称为当前 url
eg: <bean name="/hello01" class="controller.HelloController01"/>
SimpleUrlHandlerMapping 处理通过配置设置到处理对象
eg:

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello02">helloController02</prop>
<prop key="/hello03">helloController03</prop>
</props>
</property>
</bean>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
// 截取用于匹配的URL有效路径
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
request.setAttribute(LOOKUP_PATH, lookupPath);
// 根据路径寻找handler,此处并不是直接从map中获取,很多handler都有通配符的写法,甚至有多个匹配项,此时需要做好选择
Object handler = lookupHandler(lookupPath, request);
// 如果找不到处理器,则使用rootHandler或defaultHandler处理器
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;
// 如果是根路径,则使用rootHandler处理器
if (StringUtils.matchesCharacter(lookupPath, '/')) {
// 如果请求的路径仅仅是“/”,那么使用RootHandler进行处理
rawHandler = getRootHandler();
}
// 如果无法找到handler,则使用默认的handler
if (rawHandler == null) {
rawHandler = getDefaultHandler();
}
if (rawHandler != null) {
// Bean name or resolved handler?
// 如果找到的处理器是String类型,则从容器中找到该beanName对应的Bean作为处理器
if (rawHandler instanceof String) {
String handlerName = (String) rawHandler;
rawHandler = obtainApplicationContext().getBean(handlerName);
}
// 空方法,校验处理器。目前暂无子类实现该方法
validateHandler(rawHandler, request);
// 创建处理器(HandlerExecutionChain对象)
handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
}
}
return handler;
}

org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#lookupHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
// Direct match?
// 直接根据url进行查找handler
Object handler = this.handlerMap.get(urlPath);
if (handler != null) {
// Bean name or resolved handler?
// 如果找到的处理器是String类型,则从容器中找到该beanName对应的Bean作为处理器
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 空方法,校验处理器。目前暂无子类实现该方法
validateHandler(handler, request);
// 创建处理器
return buildPathExposingHandler(handler, urlPath, urlPath, null);
}

// Pattern match?
// 通过表达式进行匹配具体通过antPathMatcher实现
List<String> matchingPatterns = new ArrayList<>();
// 情况二,Pattern匹配合适的,并添加到 matchingPatterns 中
for (String registeredPattern : this.handlerMap.keySet()) {
if (getPathMatcher().match(registeredPattern, urlPath)) {
// 路径通过Pattern匹配成功
matchingPatterns.add(registeredPattern);
}
else if (useTrailingSlashMatch()) {
if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", urlPath)) {
matchingPatterns.add(registeredPattern + "/");
}
}
}

// 获得首个匹配(最优)的结果
String bestMatch = null;
Comparator<String> patternComparator = getPathMatcher().getPatternComparator(urlPath);
if (!matchingPatterns.isEmpty()) {
// 排序
matchingPatterns.sort(patternComparator);
if (logger.isTraceEnabled() && matchingPatterns.size() > 1) {
logger.trace("Matching patterns " + matchingPatterns);
}
bestMatch = matchingPatterns.get(0);
}
if (bestMatch != null) {
// 获得bestMatch对应的处理器
handler = this.handlerMap.get(bestMatch);
if (handler == null) {
if (bestMatch.endsWith("/")) {
handler = this.handlerMap.get(bestMatch.substring(0, bestMatch.length() - 1));
}
// 如果获得不到,抛出IllegalStateException异常
if (handler == null) {
throw new IllegalStateException(
"Could not find handler for best pattern match [" + bestMatch + "]");
}
}
// Bean name or resolved handler?
// 如果找到的处理器是String类型,则从容器中找到该beanName对应的Bean作为处理器
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 空方法,校验处理器。目前暂无子类实现该方法
validateHandler(handler, request);
// 获得最匹配的路径
String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestMatch, urlPath);

// There might be multiple 'best patterns', let's make sure we have the correct URI template variables
// for all of them
// 之前通过sort方法进行排序,然后拿第一个作为bestPatternMatch的,不过有可能有多个pattern的顺序相同,也就是sort方法返回0,这里就是处理这种情况
Map<String, String> uriTemplateVariables = new LinkedHashMap<>();
for (String matchingPattern : matchingPatterns) {
if (patternComparator.compare(bestMatch, matchingPattern) == 0) {
Map<String, String> vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);
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;
}

org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
// 创建 HandlerExecutionChain 对象
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

// 获得请求路径
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, LOOKUP_PATH);
// 遍历 adaptedInterceptors 数组,获得请求匹配的拦截器
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
// 需要匹配,若路径匹配,则添加到 chain 中
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
// 无需匹配,直接添加到 chain 中
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}

DispatcherServlet#getHandlerAdapter

定位: org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter

1
2
3
4
5
6
7
8
9
10
11
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");
}

HandlerExecutionChain#applyPreHandle

定位: org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* 获取拦截器数组,然后循环调用执行preHandle, interceptorIndex 这个变量设计的比较巧妙,
* 假设现在有3个拦截器,第3个拦截器的 preHandler 返回 false,那么 interceptorIndex 此时为1,会执行 triggerAfterCompletion 方法
* 第1个开始往前 大于等于0的拦截器对应上面的例子就是第2和3的拦截器的afterCompletion方法会执行
*/
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 获取拦截器数组
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
// 遍历拦截器数组
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
// 前置处理
if (!interceptor.preHandle(request, response, this.handler)) {
// 已完成处理拦截器
triggerAfterCompletion(request, response, null);
// 返回false,前置处理失败
return false;
}
// 标记interceptorIndex位置
this.interceptorIndex = i;
}
}
return true;
}
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
throws Exception {
// 获得拦截器数组
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
// 遍历拦截器数组,倒序
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try {
// 已完成处理拦截器
interceptor.afterCompletion(request, response, this.handler, ex);
}
catch (Throwable ex2) {
// 如果执行失败,仅仅会打印错误日志,不会结束循环
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}