Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
普通程序员一名
spring-framework
提交
69bbdce8
S
spring-framework
项目概览
普通程序员一名
/
spring-framework
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
69bbdce8
编写于
4月 16, 2021
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
HandlerMappingIntrospector ensures initialized RequestPath
Closes gh-26814
上级
0f31830a
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
117 addition
and
44 deletion
+117
-44
spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
...va/org/springframework/web/servlet/DispatcherServlet.java
+3
-1
spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java
...ework/web/servlet/handler/HandlerMappingIntrospector.java
+76
-36
spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java
...b/servlet/handler/PathPatternMatchableHandlerMapping.java
+37
-1
spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingIntrospectorTests.java
.../web/servlet/handler/HandlerMappingIntrospectorTests.java
+1
-6
未找到文件。
spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
浏览文件 @
69bbdce8
...
...
@@ -968,7 +968,9 @@ public class DispatcherServlet extends FrameworkServlet {
restoreAttributesAfterInclude
(
request
,
attributesSnapshot
);
}
}
ServletRequestPathUtils
.
setParsedRequestPath
(
previousRequestPath
,
request
);
if
(
this
.
parseRequestPath
)
{
ServletRequestPathUtils
.
setParsedRequestPath
(
previousRequestPath
,
request
);
}
}
}
...
...
spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java
浏览文件 @
69bbdce8
/*
* Copyright 2002-202
0
the original author or authors.
* Copyright 2002-202
1
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -23,6 +23,7 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Properties
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.function.BiFunction
;
import
java.util.stream.Collectors
;
import
javax.servlet.http.HttpServletRequest
;
...
...
@@ -36,6 +37,7 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.support.PropertiesLoaderUtils
;
import
org.springframework.http.server.RequestPath
;
import
org.springframework.lang.Nullable
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ClassUtils
;
...
...
@@ -46,6 +48,7 @@ import org.springframework.web.servlet.DispatcherServlet;
import
org.springframework.web.servlet.HandlerExecutionChain
;
import
org.springframework.web.servlet.HandlerInterceptor
;
import
org.springframework.web.servlet.HandlerMapping
;
import
org.springframework.web.util.ServletRequestPathUtils
;
import
org.springframework.web.util.UrlPathHelper
;
/**
...
...
@@ -79,8 +82,7 @@ public class HandlerMappingIntrospector
private
List
<
HandlerMapping
>
handlerMappings
;
@Nullable
private
Map
<
HandlerMapping
,
MatchableHandlerMapping
>
pathPatternMatchableHandlerMappings
=
new
ConcurrentHashMap
<>();
private
Map
<
HandlerMapping
,
PathPatternMatchableHandlerMapping
>
pathPatternHandlerMappings
=
new
ConcurrentHashMap
<>();
/**
...
...
@@ -119,7 +121,7 @@ public class HandlerMappingIntrospector
if
(
this
.
handlerMappings
==
null
)
{
Assert
.
notNull
(
this
.
applicationContext
,
"No ApplicationContext"
);
this
.
handlerMappings
=
initHandlerMappings
(
this
.
applicationContext
);
this
.
pathPattern
Matchable
HandlerMappings
=
initPathPatternMatchableHandlerMappings
(
this
.
handlerMappings
);
this
.
pathPatternHandlerMappings
=
initPathPatternMatchableHandlerMappings
(
this
.
handlerMappings
);
}
}
...
...
@@ -136,51 +138,90 @@ public class HandlerMappingIntrospector
*/
@Nullable
public
MatchableHandlerMapping
getMatchableHandlerMapping
(
HttpServletRequest
request
)
throws
Exception
{
Assert
.
notNull
(
this
.
handlerMappings
,
"Handler mappings not initialized"
);
Assert
.
notNull
(
this
.
pathPatternMatchableHandlerMappings
,
"Handler mappings with PathPatterns not initialized"
);
HttpServletRequest
wrapper
=
new
RequestAttributeChangeIgnoringWrapper
(
request
);
for
(
HandlerMapping
handlerMapping
:
this
.
handlerMappings
)
{
Object
handler
=
handlerMapping
.
getHandler
(
wrapper
);
if
(
handler
==
null
)
{
continue
;
}
if
(
handlerMapping
instanceof
MatchableHandlerMapping
)
{
return
this
.
pathPatternMatchableHandlerMappings
.
getOrDefault
(
handlerMapping
,
(
MatchableHandlerMapping
)
handlerMapping
);
HttpServletRequest
wrappedRequest
=
new
RequestAttributeChangeIgnoringWrapper
(
request
);
return
doWithMatchingMapping
(
wrappedRequest
,
false
,
(
matchedMapping
,
executionChain
)
->
{
if
(
matchedMapping
instanceof
MatchableHandlerMapping
)
{
PathPatternMatchableHandlerMapping
mapping
=
this
.
pathPatternHandlerMappings
.
get
(
matchedMapping
);
if
(
mapping
!=
null
)
{
RequestPath
requestPath
=
ServletRequestPathUtils
.
getParsedRequestPath
(
request
);
return
mapping
.
decorate
(
requestPath
)
;
}
else
{
return
(
MatchableHandlerMapping
)
matchedMapping
;
}
}
throw
new
IllegalStateException
(
"HandlerMapping is not a MatchableHandlerMapping"
);
}
return
null
;
});
}
@Override
@Nullable
public
CorsConfiguration
getCorsConfiguration
(
HttpServletRequest
request
)
{
Assert
.
notNull
(
this
.
handlerMappings
,
"Handler mappings not initialized"
);
RequestAttributeChangeIgnoringWrapper
wrapper
=
new
RequestAttributeChangeIgnoringWrapper
(
request
);
for
(
HandlerMapping
handlerMapping
:
this
.
handlerMappings
)
{
HandlerExecutionChain
handler
=
null
;
try
{
handler
=
handlerMapping
.
getHandler
(
wrapper
);
}
catch
(
Exception
ex
)
{
// Ignore
RequestAttributeChangeIgnoringWrapper
wrappedRequest
=
new
RequestAttributeChangeIgnoringWrapper
(
request
);
return
doWithMatchingMappingIgnoringException
(
wrappedRequest
,
(
handlerMapping
,
executionChain
)
->
{
for
(
HandlerInterceptor
interceptor
:
executionChain
.
getInterceptorList
())
{
if
(
interceptor
instanceof
CorsConfigurationSource
)
{
return
((
CorsConfigurationSource
)
interceptor
).
getCorsConfiguration
(
wrappedRequest
);
}
}
if
(
handler
==
null
)
{
continue
;
if
(
executionChain
.
getHandler
()
instanceof
CorsConfigurationSource
)
{
return
((
CorsConfigurationSource
)
executionChain
.
getHandler
()).
getCorsConfiguration
(
wrappedRequest
)
;
}
for
(
HandlerInterceptor
interceptor
:
handler
.
getInterceptorList
())
{
if
(
interceptor
instanceof
CorsConfigurationSource
)
{
return
((
CorsConfigurationSource
)
interceptor
).
getCorsConfiguration
(
wrapper
);
return
null
;
});
}
@Nullable
private
<
T
>
T
doWithMatchingMapping
(
HttpServletRequest
request
,
boolean
ignoreException
,
BiFunction
<
HandlerMapping
,
HandlerExecutionChain
,
T
>
matchHandler
)
throws
Exception
{
Assert
.
notNull
(
this
.
handlerMappings
,
"Handler mappings not initialized"
);
Assert
.
notNull
(
this
.
pathPatternHandlerMappings
,
"Handler mappings with PathPatterns not initialized"
);
boolean
parseRequestPath
=
!
this
.
pathPatternHandlerMappings
.
isEmpty
();
RequestPath
previousPath
=
null
;
if
(
parseRequestPath
)
{
previousPath
=
(
RequestPath
)
request
.
getAttribute
(
ServletRequestPathUtils
.
PATH_ATTRIBUTE
);
ServletRequestPathUtils
.
parseAndCache
(
request
);
}
try
{
for
(
HandlerMapping
handlerMapping
:
this
.
handlerMappings
)
{
HandlerExecutionChain
chain
=
null
;
try
{
chain
=
handlerMapping
.
getHandler
(
request
);
}
catch
(
Exception
ex
)
{
if
(!
ignoreException
)
{
throw
ex
;
}
}
if
(
chain
==
null
)
{
continue
;
}
return
matchHandler
.
apply
(
handlerMapping
,
chain
);
}
if
(
handler
.
getHandler
()
instanceof
CorsConfigurationSource
)
{
return
((
CorsConfigurationSource
)
handler
.
getHandler
()).
getCorsConfiguration
(
wrapper
);
}
finally
{
if
(
parseRequestPath
)
{
ServletRequestPathUtils
.
setParsedRequestPath
(
previousPath
,
request
);
}
}
return
null
;
}
@Nullable
private
<
T
>
T
doWithMatchingMappingIgnoringException
(
HttpServletRequest
request
,
BiFunction
<
HandlerMapping
,
HandlerExecutionChain
,
T
>
matchHandler
)
{
try
{
return
doWithMatchingMapping
(
request
,
true
,
matchHandler
);
}
catch
(
Exception
ex
)
{
throw
new
IllegalStateException
(
"HandlerMapping exception not suppressed"
,
ex
);
}
}
private
static
List
<
HandlerMapping
>
initHandlerMappings
(
ApplicationContext
applicationContext
)
{
Map
<
String
,
HandlerMapping
>
beans
=
BeanFactoryUtils
.
beansOfTypeIncludingAncestors
(
...
...
@@ -219,7 +260,7 @@ public class HandlerMappingIntrospector
return
result
;
}
private
static
Map
<
HandlerMapping
,
MatchableHandlerMapping
>
initPathPatternMatchableHandlerMappings
(
private
static
Map
<
HandlerMapping
,
PathPattern
MatchableHandlerMapping
>
initPathPatternMatchableHandlerMappings
(
List
<
HandlerMapping
>
mappings
)
{
return
mappings
.
stream
()
...
...
@@ -241,8 +282,7 @@ public class HandlerMappingIntrospector
@Override
public
void
setAttribute
(
String
name
,
Object
value
)
{
// Allow UrlPathHelper-resolved lookupPath to be saved for efficiency
if
(
name
.
equals
(
UrlPathHelper
.
PATH_ATTRIBUTE
))
{
if
(
name
.
equals
(
ServletRequestPathUtils
.
PATH_ATTRIBUTE
)
||
name
.
equals
(
UrlPathHelper
.
PATH_ATTRIBUTE
))
{
super
.
setAttribute
(
name
,
value
);
}
}
...
...
spring-webmvc/src/main/java/org/springframework/web/servlet/handler/PathPatternMatchableHandlerMapping.java
浏览文件 @
69bbdce8
/*
* Copyright 2002-202
0
the original author or authors.
* Copyright 2002-202
1
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -21,6 +21,7 @@ import java.util.concurrent.ConcurrentHashMap;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.http.server.PathContainer
;
import
org.springframework.http.server.RequestPath
;
import
org.springframework.lang.Nullable
;
import
org.springframework.util.Assert
;
import
org.springframework.web.servlet.HandlerExecutionChain
;
...
...
@@ -70,4 +71,39 @@ class PathPatternMatchableHandlerMapping implements MatchableHandlerMapping {
public
HandlerExecutionChain
getHandler
(
HttpServletRequest
request
)
throws
Exception
{
return
this
.
delegate
.
getHandler
(
request
);
}
MatchableHandlerMapping
decorate
(
RequestPath
requestPath
)
{
return
new
MatchableHandlerMapping
()
{
@Nullable
@Override
public
RequestMatchResult
match
(
HttpServletRequest
request
,
String
pattern
)
{
RequestPath
previousPath
=
setRequestPathAttribute
(
request
);
try
{
return
PathPatternMatchableHandlerMapping
.
this
.
match
(
request
,
pattern
);
}
finally
{
ServletRequestPathUtils
.
setParsedRequestPath
(
previousPath
,
request
);
}
}
@Nullable
@Override
public
HandlerExecutionChain
getHandler
(
HttpServletRequest
request
)
throws
Exception
{
RequestPath
previousPath
=
setRequestPathAttribute
(
request
);
try
{
return
PathPatternMatchableHandlerMapping
.
this
.
getHandler
(
request
);
}
finally
{
ServletRequestPathUtils
.
setParsedRequestPath
(
previousPath
,
request
);
}
}
private
RequestPath
setRequestPathAttribute
(
HttpServletRequest
request
)
{
RequestPath
previous
=
(
RequestPath
)
request
.
getAttribute
(
ServletRequestPathUtils
.
PATH_ATTRIBUTE
);
ServletRequestPathUtils
.
setParsedRequestPath
(
requestPath
,
request
);
return
previous
;
}
};
}
}
spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMappingIntrospectorTests.java
浏览文件 @
69bbdce8
...
...
@@ -127,16 +127,11 @@ public class HandlerMappingIntrospectorTests {
context
.
refresh
();
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/path/123"
);
// Initialize the RequestPath. At runtime, ServletRequestPathFilter is expected to do that.
if
(
usePathPatterns
)
{
ServletRequestPathUtils
.
parseAndCache
(
request
);
}
MatchableHandlerMapping
mapping
=
initIntrospector
(
context
).
getMatchableHandlerMapping
(
request
);
assertThat
(
mapping
).
isNotNull
();
assertThat
(
request
.
getAttribute
(
BEST_MATCHING_PATTERN_ATTRIBUTE
)).
as
(
"Attribute changes not ignored"
).
isNull
();
assertThat
(
request
.
getAttribute
(
ServletRequestPathUtils
.
PATH_ATTRIBUTE
)).
as
(
"Parsed path not cleaned"
).
isNull
();
assertThat
(
mapping
.
match
(
request
,
"/p*/*"
)).
isNotNull
();
assertThat
(
mapping
.
match
(
request
,
"/b*/*"
)).
isNull
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录