Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dk131072
spring-framework
提交
96b0752d
S
spring-framework
项目概览
dk131072
/
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,发现更多精彩内容 >>
提交
96b0752d
编写于
6月 17, 2011
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SPR-7812 RequestCondition refactoring with the possibility for custom request conditions in mind.
上级
3a332e55
变更
24
隐藏空白更改
内联
并排
Showing
24 changed file
with
1228 addition
and
1276 deletion
+1228
-1276
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java
...gframework/web/servlet/mvc/method/RequestMappingInfo.java
+51
-153
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java
.../servlet/mvc/method/RequestMappingInfoHandlerMapping.java
+24
-58
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
...t/mvc/method/annotation/RequestMappingHandlerMapping.java
+15
-10
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/AbstractNameValueExpression.java
...let/mvc/method/condition/AbstractNameValueExpression.java
+19
-4
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ConsumesRequestCondition.java
...ervlet/mvc/method/condition/ConsumesRequestCondition.java
+128
-74
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestCondition.java
...servlet/mvc/method/condition/HeadersRequestCondition.java
+82
-60
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalConjunctionRequestCondition.java
.../method/condition/LogicalConjunctionRequestCondition.java
+0
-54
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/MediaTypeExpression.java
...web/servlet/mvc/method/condition/MediaTypeExpression.java
+96
-0
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/MediaTypesRequestCondition.java
...vlet/mvc/method/condition/MediaTypesRequestCondition.java
+0
-126
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestCondition.java
.../servlet/mvc/method/condition/ParamsRequestCondition.java
+68
-56
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/PatternsRequestCondition.java
...ervlet/mvc/method/condition/PatternsRequestCondition.java
+228
-0
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ProducesRequestCondition.java
...ervlet/mvc/method/condition/ProducesRequestCondition.java
+129
-55
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition.java
...rk/web/servlet/mvc/method/condition/RequestCondition.java
+27
-11
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionFactory.java
...servlet/mvc/method/condition/RequestConditionFactory.java
+0
-194
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionSupport.java
...servlet/mvc/method/condition/RequestConditionSupport.java
+29
-31
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestCondition.java
.../mvc/method/condition/RequestMethodsRequestCondition.java
+61
-91
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoComparatorTests.java
...servlet/mvc/method/RequestMappingInfoComparatorTests.java
+22
-19
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java
...let/mvc/method/RequestMappingInfoHandlerMappingTests.java
+14
-10
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java
...ework/web/servlet/mvc/method/RequestMappingInfoTests.java
+95
-119
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/ConsumesRequestConditionTests.java
...t/mvc/method/condition/ConsumesRequestConditionTests.java
+31
-46
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestConditionTests.java
...et/mvc/method/condition/HeadersRequestConditionTests.java
+27
-21
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestConditionTests.java
...let/mvc/method/condition/ParamsRequestConditionTests.java
+23
-17
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/ProducesRequestConditionTests.java
...t/mvc/method/condition/ProducesRequestConditionTests.java
+46
-56
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestConditionTests.java
...method/condition/RequestMethodsRequestConditionTests.java
+13
-11
未找到文件。
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java
浏览文件 @
96b0752d
...
...
@@ -16,31 +16,19 @@
package
org.springframework.web.servlet.mvc.method
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.util.PathMatcher
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.servlet.mvc.method.condition.ConsumesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ParamsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.PatternsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ProducesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory
;
import
org.springframework.web.servlet.mvc.method.condition.RequestMethodsRequestCondition
;
/**
* Contains a set of conditions to match to a given request such as URL patterns, HTTP methods, request parameters
* and headers.
*
* <p>Two {@link RequestMappingInfo}s can be combined resulting in a new {@link RequestMappingInfo} with conditions
* from both. A {@link RequestMappingInfo} can also match itself to an HTTP request resulting in a new
* {@link RequestMappingInfo} with the subset of conditions relevant to the request.
* Contains request mapping conditions to be matched to a given request.
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
...
...
@@ -48,7 +36,7 @@ import org.springframework.web.servlet.mvc.method.condition.RequestMethodsReques
*/
public
final
class
RequestMappingInfo
{
private
final
Set
<
String
>
patterns
;
private
final
PatternsRequestCondition
patternsCondition
;
private
final
RequestMethodsRequestCondition
methodsCondition
;
...
...
@@ -63,24 +51,15 @@ public final class RequestMappingInfo {
private
int
hash
;
/**
* Creates a new {@code RequestMappingInfo} instance with the given URL patterns and HTTP methods.
*
* <p>Package protected for testing purposes.
*/
RequestMappingInfo
(
Collection
<
String
>
patterns
,
RequestMethod
[]
methods
)
{
this
(
patterns
,
RequestConditionFactory
.
parseMethods
(
methods
),
null
,
null
,
null
,
null
);
}
/**
* Creates a new {@code RequestMappingInfo} instance with a full set of conditions.
* Creates a new {@code RequestMappingInfo} instance.
*/
public
RequestMappingInfo
(
Collection
<
String
>
patterns
,
RequestMethodsRequestCondition
methodsCondition
,
ParamsRequestCondition
paramsCondition
,
HeadersRequestCondition
headersCondition
,
ConsumesRequestCondition
consumesCondition
,
ProducesRequestCondition
producesCondition
)
{
this
.
patterns
=
asUnmodifiableSet
(
prependLeadingSlash
(
patterns
)
);
public
RequestMappingInfo
(
PatternsRequestCondition
patternsCondition
,
RequestMethodsRequestCondition
methodsCondition
,
ParamsRequestCondition
paramsCondition
,
HeadersRequestCondition
headersCondition
,
ConsumesRequestCondition
consumesCondition
,
ProducesRequestCondition
producesCondition
)
{
this
.
patterns
Condition
=
patternsCondition
!=
null
?
patternsCondition
:
new
PatternsRequestCondition
(
);
this
.
methodsCondition
=
methodsCondition
!=
null
?
methodsCondition
:
new
RequestMethodsRequestCondition
();
this
.
paramsCondition
=
paramsCondition
!=
null
?
paramsCondition
:
new
ParamsRequestCondition
();
this
.
headersCondition
=
headersCondition
!=
null
?
headersCondition
:
new
HeadersRequestCondition
();
...
...
@@ -88,67 +67,52 @@ public final class RequestMappingInfo {
this
.
producesCondition
=
producesCondition
!=
null
?
producesCondition
:
new
ProducesRequestCondition
();
}
private
static
Set
<
String
>
prependLeadingSlash
(
Collection
<
String
>
patterns
)
{
if
(
patterns
==
null
)
{
return
Collections
.
emptySet
();
}
Set
<
String
>
result
=
new
LinkedHashSet
<
String
>(
patterns
.
size
());
for
(
String
pattern
:
patterns
)
{
if
(
StringUtils
.
hasLength
(
pattern
)
&&
!
pattern
.
startsWith
(
"/"
))
{
pattern
=
"/"
+
pattern
;
}
result
.
add
(
pattern
);
}
return
result
;
}
private
static
<
T
>
Set
<
T
>
asUnmodifiableSet
(
Collection
<
T
>
collection
)
{
if
(
collection
==
null
)
{
return
Collections
.
emptySet
();
}
Set
<
T
>
result
=
new
LinkedHashSet
<
T
>(
collection
);
return
Collections
.
unmodifiableSet
(
result
);
/**
* Package protected, used for testing.
*/
RequestMappingInfo
(
String
[]
patterns
,
RequestMethod
...
methods
)
{
this
(
new
PatternsRequestCondition
(
patterns
),
new
RequestMethodsRequestCondition
(
methods
),
null
,
null
,
null
,
null
);
}
/**
* Returns the patterns of this request mapping info.
*/
public
Set
<
String
>
getPatterns
()
{
return
patterns
;
public
PatternsRequestCondition
getPatternsCondition
()
{
return
patterns
Condition
;
}
/**
* Returns the request method condition
s
of this request mapping info.
* Returns the request method condition of this request mapping info.
*/
public
RequestMethodsRequestCondition
getMethods
()
{
public
RequestMethodsRequestCondition
getMethods
Condition
()
{
return
methodsCondition
;
}
/**
* Returns the request parameters condition
s
of this request mapping info.
* Returns the request parameters condition of this request mapping info.
*/
public
ParamsRequestCondition
getParams
()
{
public
ParamsRequestCondition
getParams
Condition
()
{
return
paramsCondition
;
}
/**
* Returns the request headers condition
s
of this request mapping info.
* Returns the request headers condition of this request mapping info.
*/
public
HeadersRequestCondition
getHeaders
()
{
public
HeadersRequestCondition
getHeaders
Condition
()
{
return
headersCondition
;
}
/**
* Returns the request consumes condition
s
of this request mapping info.
* Returns the request consumes condition of this request mapping info.
*/
public
ConsumesRequestCondition
getConsumes
()
{
public
ConsumesRequestCondition
getConsumes
Condition
()
{
return
consumesCondition
;
}
/**
* Returns the request produces condition
s
of this request mapping info.
* Returns the request produces condition of this request mapping info.
*/
public
ProducesRequestCondition
getProduces
()
{
public
ProducesRequestCondition
getProduces
Condition
()
{
return
producesCondition
;
}
...
...
@@ -167,110 +131,44 @@ public final class RequestMappingInfo {
* <li>Consumes are combined as per {@link ConsumesRequestCondition#combine(ConsumesRequestCondition)}.
* </ul>
* @param methodKey the key to combine with
* @param pathMatcher to {@linkplain PathMatcher#combine(String, String) combine} the patterns
* @return a new request mapping info containing conditions from both keys
*/
public
RequestMappingInfo
combine
(
RequestMappingInfo
methodKey
,
PathMatcher
pathMatcher
)
{
Set
<
String
>
patterns
=
combinePatterns
(
this
.
patterns
,
methodKey
.
patterns
,
pathMatcher
);
public
RequestMappingInfo
combine
(
RequestMappingInfo
methodKey
)
{
PatternsRequestCondition
patterns
=
this
.
patternsCondition
.
combine
(
methodKey
.
patternsCondition
);
RequestMethodsRequestCondition
methods
=
this
.
methodsCondition
.
combine
(
methodKey
.
methodsCondition
);
ParamsRequestCondition
params
=
this
.
paramsCondition
.
combine
(
methodKey
.
paramsCondition
);
HeadersRequestCondition
headers
=
this
.
headersCondition
.
combine
(
methodKey
.
headersCondition
);
ConsumesRequestCondition
consumes
=
this
.
consumesCondition
.
combine
(
methodKey
.
consumesCondition
);
ProducesRequestCondition
produces
=
this
.
producesCondition
.
combine
(
methodKey
.
producesCondition
);
return
new
RequestMappingInfo
(
patterns
,
methods
,
params
,
headers
,
consumes
,
produces
);
}
private
static
Set
<
String
>
combinePatterns
(
Collection
<
String
>
typePatterns
,
Collection
<
String
>
methodPatterns
,
PathMatcher
pathMatcher
)
{
Set
<
String
>
result
=
new
LinkedHashSet
<
String
>();
if
(!
typePatterns
.
isEmpty
()
&&
!
methodPatterns
.
isEmpty
())
{
for
(
String
pattern1
:
typePatterns
)
{
for
(
String
pattern2
:
methodPatterns
)
{
result
.
add
(
pathMatcher
.
combine
(
pattern1
,
pattern2
));
}
}
}
else
if
(!
typePatterns
.
isEmpty
())
{
result
.
addAll
(
typePatterns
);
}
else
if
(!
methodPatterns
.
isEmpty
())
{
result
.
addAll
(
methodPatterns
);
}
else
{
result
.
add
(
""
);
}
return
result
;
}
/**
* Returns a new {@code RequestMappingInfo} that contains all conditions of this key that are relevant to the request.
* <ul>
* <li>The list of URL path patterns is trimmed to contain the patterns that match the URL with matching patterns
* sorted via {@link PathMatcher#getPatternComparator(String)}.
* <li>The list of HTTP methods is trimmed to contain only the method of the request.
* <li>Request parameter and request header conditions are included in full.
* <li>The list of consumes conditions is trimmed and sorted to match the request "Content-Type" header.
* </ul>
* @param lookupPath mapping lookup path within the current servlet mapping if applicable
* Returns a new {@code RequestMappingInfo} with conditions relevant to the current request.
* For example the list of URL path patterns is trimmed to contain the patterns that match the URL.
* @param request the current request
* @param pathMatcher to check for matching patterns
* @return a new request mapping info that contains all matching attributes, or {@code null} if not all conditions match
*/
public
RequestMappingInfo
getMatchingRequestMapping
(
String
lookupPath
,
HttpServletRequest
request
,
PathMatcher
pathMatcher
)
{
RequestMethodsRequestCondition
matchingMethod
Condition
=
methodsCondition
.
getMatchingCondition
(
request
);
ParamsRequestCondition
matchingParams
Condition
=
paramsCondition
.
getMatchingCondition
(
request
);
HeadersRequestCondition
matchingHeaders
Condition
=
headersCondition
.
getMatchingCondition
(
request
);
ConsumesRequestCondition
matchingConsumes
Condition
=
consumesCondition
.
getMatchingCondition
(
request
);
ProducesRequestCondition
matchingProduces
Condition
=
producesCondition
.
getMatchingCondition
(
request
);
if
(
matchingMethod
Condition
==
null
||
matchingParamsCondition
==
null
||
matchingHeadersCondition
==
null
||
matchingConsumes
Condition
==
null
||
matchingProducesCondition
==
null
)
{
public
RequestMappingInfo
getMatchingRequestMapping
(
HttpServletRequest
request
)
{
RequestMethodsRequestCondition
matchingMethod
=
methodsCondition
.
getMatchingCondition
(
request
);
ParamsRequestCondition
matchingParams
=
paramsCondition
.
getMatchingCondition
(
request
);
HeadersRequestCondition
matchingHeaders
=
headersCondition
.
getMatchingCondition
(
request
);
ConsumesRequestCondition
matchingConsumes
=
consumesCondition
.
getMatchingCondition
(
request
);
ProducesRequestCondition
matchingProduces
=
producesCondition
.
getMatchingCondition
(
request
);
if
(
matchingMethod
==
null
||
matchingParams
==
null
||
matchingHeaders
==
null
||
matchingConsumes
==
null
||
matchingProduces
==
null
)
{
return
null
;
}
else
{
List
<
String
>
matchingPatterns
=
getMatchingPatterns
(
lookupPath
,
pathMatcher
);
if
(!
matchingPatterns
.
isEmpty
())
{
return
new
RequestMappingInfo
(
matchingPatterns
,
matchingMethodCondition
,
matchingParamsCondition
,
matchingHeadersCondition
,
matchingConsumesCondition
,
matchingProducesCondition
);
}
else
{
return
null
;
}
PatternsRequestCondition
matchingPatterns
=
patternsCondition
.
getMatchingCondition
(
request
);
if
(
matchingPatterns
!=
null
)
{
return
new
RequestMappingInfo
(
matchingPatterns
,
matchingMethod
,
matchingParams
,
matchingHeaders
,
matchingConsumes
,
matchingProduces
);
}
}
private
List
<
String
>
getMatchingPatterns
(
String
lookupPath
,
PathMatcher
pathMatcher
)
{
List
<
String
>
matchingPatterns
=
new
ArrayList
<
String
>();
for
(
String
pattern
:
this
.
patterns
)
{
String
matchingPattern
=
getMatchingPattern
(
pattern
,
lookupPath
,
pathMatcher
);
if
(
matchingPattern
!=
null
)
{
matchingPatterns
.
add
(
matchingPattern
);
}
}
Collections
.
sort
(
matchingPatterns
,
pathMatcher
.
getPatternComparator
(
lookupPath
));
return
matchingPatterns
;
}
private
String
getMatchingPattern
(
String
pattern
,
String
lookupPath
,
PathMatcher
pathMatcher
)
{
if
(
pattern
.
equals
(
lookupPath
))
{
return
pattern
;
}
boolean
hasSuffix
=
pattern
.
indexOf
(
'.'
)
!=
-
1
;
if
(!
hasSuffix
&&
pathMatcher
.
match
(
pattern
+
".*"
,
lookupPath
))
{
return
pattern
+
".*"
;
}
if
(
pathMatcher
.
match
(
pattern
,
lookupPath
))
{
return
pattern
;
}
boolean
endsWithSlash
=
pattern
.
endsWith
(
"/"
);
if
(!
endsWithSlash
&&
pathMatcher
.
match
(
pattern
+
"/"
,
lookupPath
))
{
return
pattern
+
"/"
;
}
return
null
;
}
...
...
@@ -281,7 +179,7 @@ public final class RequestMappingInfo {
}
if
(
obj
!=
null
&&
obj
instanceof
RequestMappingInfo
)
{
RequestMappingInfo
other
=
(
RequestMappingInfo
)
obj
;
return
(
this
.
patterns
.
equals
(
other
.
patterns
)
&&
return
(
this
.
patterns
Condition
.
equals
(
other
.
patternsCondition
)
&&
this
.
methodsCondition
.
equals
(
other
.
methodsCondition
)
&&
this
.
paramsCondition
.
equals
(
other
.
paramsCondition
)
&&
this
.
headersCondition
.
equals
(
other
.
headersCondition
)
&&
...
...
@@ -295,7 +193,7 @@ public final class RequestMappingInfo {
public
int
hashCode
()
{
int
result
=
hash
;
if
(
result
==
0
)
{
result
=
patterns
.
hashCode
();
result
=
patterns
Condition
.
hashCode
();
result
=
31
*
result
+
methodsCondition
.
hashCode
();
result
=
31
*
result
+
paramsCondition
.
hashCode
();
result
=
31
*
result
+
headersCondition
.
hashCode
();
...
...
@@ -309,7 +207,7 @@ public final class RequestMappingInfo {
@Override
public
String
toString
()
{
StringBuilder
builder
=
new
StringBuilder
(
"{"
);
builder
.
append
(
patterns
);
builder
.
append
(
patterns
Condition
);
builder
.
append
(
",methods="
).
append
(
methodsCondition
);
builder
.
append
(
",params="
).
append
(
paramsCondition
);
builder
.
append
(
",headers="
).
append
(
headersCondition
);
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java
浏览文件 @
96b0752d
...
...
@@ -19,7 +19,6 @@ package org.springframework.web.servlet.mvc.method;
import
java.util.ArrayList
;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
...
...
@@ -61,7 +60,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
@Override
protected
Set
<
String
>
getMappingPaths
(
RequestMappingInfo
mapping
)
{
return
mapping
.
getPatterns
();
return
mapping
.
getPatterns
Condition
().
getPatterns
();
}
/**
...
...
@@ -73,7 +72,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
protected
RequestMappingInfo
getMatchingMapping
(
RequestMappingInfo
mapping
,
String
lookupPath
,
HttpServletRequest
request
)
{
return
mapping
.
getMatchingRequestMapping
(
lookupPath
,
request
,
getPathMatcher
()
);
return
mapping
.
getMatchingRequestMapping
(
request
);
}
/**
...
...
@@ -81,7 +80,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
*/
@Override
protected
Comparator
<
RequestMappingInfo
>
getMappingComparator
(
String
lookupPath
,
HttpServletRequest
request
)
{
return
new
RequestMappingInfoComparator
(
lookupPath
,
request
);
return
new
RequestMappingInfoComparator
(
request
);
}
/**
...
...
@@ -94,12 +93,12 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
protected
void
handleMatch
(
RequestMappingInfo
info
,
String
lookupPath
,
HttpServletRequest
request
)
{
super
.
handleMatch
(
info
,
lookupPath
,
request
);
String
pattern
=
info
.
getPatterns
().
iterator
().
next
();
String
pattern
=
info
.
getPatterns
Condition
().
getPatterns
().
iterator
().
next
();
Map
<
String
,
String
>
uriTemplateVariables
=
getPathMatcher
().
extractUriTemplateVariables
(
pattern
,
lookupPath
);
request
.
setAttribute
(
HandlerMapping
.
URI_TEMPLATE_VARIABLES_ATTRIBUTE
,
uriTemplateVariables
);
if
(!
info
.
getProduces
().
isEmpty
())
{
Set
<
MediaType
>
mediaTypes
=
info
.
getProduces
().
getMediaTypes
();
if
(!
info
.
getProduces
Condition
().
isEmpty
())
{
Set
<
MediaType
>
mediaTypes
=
info
.
getProduces
Condition
().
getMediaTypes
();
request
.
setAttribute
(
PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE
,
mediaTypes
);
}
}
...
...
@@ -117,18 +116,18 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
Set
<
MediaType
>
consumableMediaTypes
=
new
HashSet
<
MediaType
>();
Set
<
MediaType
>
producibleMediaTypes
=
new
HashSet
<
MediaType
>();
for
(
RequestMappingInfo
info
:
requestMappingInfos
)
{
for
(
String
pattern
:
info
.
getPatterns
())
{
for
(
String
pattern
:
info
.
getPatterns
Condition
().
getPatterns
())
{
if
(
getPathMatcher
().
match
(
pattern
,
lookupPath
))
{
if
(
!
info
.
getMethods
().
match
(
request
)
)
{
for
(
RequestMethod
method
:
info
.
getMethods
().
getMethods
())
{
if
(
info
.
getMethodsCondition
().
getMatchingCondition
(
request
)
==
null
)
{
for
(
RequestMethod
method
:
info
.
getMethods
Condition
().
getMethods
())
{
allowedMethods
.
add
(
method
.
name
());
}
}
if
(
!
info
.
getConsumes
().
match
(
request
)
)
{
consumableMediaTypes
.
addAll
(
info
.
getConsumes
().
getMediaTypes
());
if
(
info
.
getConsumesCondition
().
getMatchingCondition
(
request
)
==
null
)
{
consumableMediaTypes
.
addAll
(
info
.
getConsumes
Condition
().
getMediaTypes
());
}
if
(
!
info
.
getProduces
().
match
(
request
)
)
{
producibleMediaTypes
.
addAll
(
info
.
getProduces
().
getMediaTypes
());
if
(
info
.
getProducesCondition
().
getMatchingCondition
(
request
)
==
null
)
{
producibleMediaTypes
.
addAll
(
info
.
getProduces
Condition
().
getMediaTypes
());
}
}
}
...
...
@@ -152,77 +151,44 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
}
/**
* A comparator for {@link RequestMappingInfo}s. Effective comparison can only be done in the context of a specific
* request. For example not all {@link RequestMappingInfo} patterns may apply to the current request. Therefore an
* HttpServletRequest is required as input.
*
* <p>Furthermore, the following assumptions are made about the input RequestMappings: <ul><li>Each RequestMappingInfo
* has been fully matched to the request <li>The RequestMappingInfo contains matched patterns only <li>Patterns are
* ordered with the best matching pattern at the top </ul>
*
* @see RequestMappingInfoHandlerMapping#getMatchingMapping(RequestMappingInfo, String, HttpServletRequest)
* A comparator for {@link RequestMappingInfo}s. Effective comparison can only be done in the context
* of a specific request. For example only a subset of URL patterns may apply to the current request.
*/
private
class
RequestMappingInfoComparator
implements
Comparator
<
RequestMappingInfo
>
{
private
Comparator
<
String
>
patternComparator
;
private
List
<
MediaType
>
requestAcceptHeader
;
private
final
HttpServletRequest
request
;
public
RequestMappingInfoComparator
(
String
lookupPath
,
HttpServletRequest
request
)
{
this
.
patternComparator
=
getPathMatcher
().
getPatternComparator
(
lookupPath
);
String
acceptHeader
=
request
.
getHeader
(
"Accept"
);
this
.
requestAcceptHeader
=
MediaType
.
parseMediaTypes
(
acceptHeader
);
MediaType
.
sortByQualityValue
(
this
.
requestAcceptHeader
);
public
RequestMappingInfoComparator
(
HttpServletRequest
request
)
{
this
.
request
=
request
;
}
public
int
compare
(
RequestMappingInfo
mapping
,
RequestMappingInfo
otherMapping
)
{
int
result
=
comparePatterns
(
mapping
.
getPatterns
(),
otherMapping
.
getPatterns
()
);
int
result
=
mapping
.
getPatternsCondition
().
compareTo
(
otherMapping
.
getPatternsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getParams
().
compareTo
(
otherMapping
.
getParams
()
);
result
=
mapping
.
getParams
Condition
().
compareTo
(
otherMapping
.
getParamsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getHeaders
().
compareTo
(
otherMapping
.
getHeaders
()
);
result
=
mapping
.
getHeaders
Condition
().
compareTo
(
otherMapping
.
getHeadersCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getConsumes
().
compareTo
(
otherMapping
.
getConsumes
()
);
result
=
mapping
.
getConsumes
Condition
().
compareTo
(
otherMapping
.
getConsumesCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getProduces
().
compareTo
(
otherMapping
.
getProduces
(),
this
.
requestAcceptHeader
);
result
=
mapping
.
getProduces
Condition
().
compareTo
(
otherMapping
.
getProducesCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getMethods
().
compareTo
(
otherMapping
.
getMethods
()
);
result
=
mapping
.
getMethods
Condition
().
compareTo
(
otherMapping
.
getMethodsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
return
0
;
}
private
int
comparePatterns
(
Set
<
String
>
patterns
,
Set
<
String
>
otherPatterns
)
{
Iterator
<
String
>
iterator
=
patterns
.
iterator
();
Iterator
<
String
>
iteratorOther
=
otherPatterns
.
iterator
();
while
(
iterator
.
hasNext
()
&&
iteratorOther
.
hasNext
())
{
int
result
=
patternComparator
.
compare
(
iterator
.
next
(),
iteratorOther
.
next
());
if
(
result
!=
0
)
{
return
result
;
}
}
if
(
iterator
.
hasNext
())
{
return
-
1
;
}
else
if
(
iteratorOther
.
hasNext
())
{
return
1
;
}
else
{
return
0
;
}
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
浏览文件 @
96b0752d
...
...
@@ -17,7 +17,6 @@
package
org.springframework.web.servlet.mvc.method.annotation
;
import
java.lang.reflect.Method
;
import
java.util.Arrays
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.stereotype.Controller
;
...
...
@@ -25,7 +24,12 @@ import org.springframework.util.PathMatcher;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping
;
import
org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory
;
import
org.springframework.web.servlet.mvc.method.condition.ConsumesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ParamsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.PatternsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ProducesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.RequestMethodsRequestCondition
;
/**
* A sub-class of {@link RequestMappingInfoHandlerMapping} that prepares {@link RequestMappingInfo}s
...
...
@@ -64,7 +68,7 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
RequestMapping
typeAnnot
=
AnnotationUtils
.
findAnnotation
(
handlerType
,
RequestMapping
.
class
);
if
(
typeAnnot
!=
null
)
{
RequestMappingInfo
typeMapping
=
createFromRequestMapping
(
typeAnnot
);
return
typeMapping
.
combine
(
methodMapping
,
getPathMatcher
()
);
return
typeMapping
.
combine
(
methodMapping
);
}
else
{
return
methodMapping
;
...
...
@@ -75,13 +79,14 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
}
}
private
static
RequestMappingInfo
createFromRequestMapping
(
RequestMapping
annotation
)
{
return
new
RequestMappingInfo
(
Arrays
.
asList
(
annotation
.
value
()),
RequestConditionFactory
.
parseMethods
(
annotation
.
method
()),
RequestConditionFactory
.
parseParams
(
annotation
.
params
()),
RequestConditionFactory
.
parseHeaders
(
annotation
.
headers
()),
RequestConditionFactory
.
parseConsumes
(
annotation
.
consumes
(),
annotation
.
headers
()),
RequestConditionFactory
.
parseProduces
(
annotation
.
produces
(),
annotation
.
headers
()));
private
RequestMappingInfo
createFromRequestMapping
(
RequestMapping
annotation
)
{
return
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
annotation
.
value
(),
getUrlPathHelper
(),
getPathMatcher
()),
new
RequestMethodsRequestCondition
(
annotation
.
method
()),
new
ParamsRequestCondition
(
annotation
.
params
()),
new
HeadersRequestCondition
(
annotation
.
headers
()),
new
ConsumesRequestCondition
(
annotation
.
consumes
(),
annotation
.
headers
()),
new
ProducesRequestCondition
(
annotation
.
produces
(),
annotation
.
headers
()));
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/AbstractNameValue
Condit
ion.java
→
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/AbstractNameValue
Express
ion.java
浏览文件 @
96b0752d
...
...
@@ -19,14 +19,15 @@ package org.springframework.web.servlet.mvc.method.condition;
import
javax.servlet.http.HttpServletRequest
;
/**
* A condition that supports simple "name=value" style expressions as documented in {@link
* org.springframework.web.bind.annotation.RequestMapping#params()} and {@link org.springframework.web.bind.annotation.RequestMapping#headers()}.
* Supports "name=value" style expressions as described in:
* {@link org.springframework.web.bind.annotation.RequestMapping#params()} and
* {@link org.springframework.web.bind.annotation.RequestMapping#headers()}.
*
* @author Rossen Stoyanchev
* @author Arjen Poutsma
* @since 3.1
*/
abstract
class
AbstractNameValue
Condition
<
T
>
implements
RequestCondition
{
abstract
class
AbstractNameValue
Expression
<
T
>
{
protected
final
String
name
;
...
...
@@ -34,7 +35,7 @@ abstract class AbstractNameValueCondition<T> implements RequestCondition {
protected
final
boolean
isNegated
;
AbstractNameValue
Condit
ion
(
String
expression
)
{
AbstractNameValue
Express
ion
(
String
expression
)
{
int
separator
=
expression
.
indexOf
(
'='
);
if
(
separator
==
-
1
)
{
this
.
isNegated
=
expression
.
startsWith
(
"!"
);
...
...
@@ -65,6 +66,20 @@ abstract class AbstractNameValueCondition<T> implements RequestCondition {
protected
abstract
boolean
matchValue
(
HttpServletRequest
request
);
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
!=
null
&&
obj
instanceof
AbstractNameValueExpression
)
{
AbstractNameValueExpression
<?>
other
=
(
AbstractNameValueExpression
<?>)
obj
;
return
((
this
.
name
.
equalsIgnoreCase
(
other
.
name
))
&&
(
this
.
value
!=
null
?
this
.
value
.
equals
(
other
.
value
)
:
other
.
value
==
null
)
&&
this
.
isNegated
==
other
.
isNegated
);
}
return
false
;
}
@Override
public
int
hashCode
()
{
int
result
=
name
.
hashCode
();
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ConsumesRequestCondition.java
浏览文件 @
96b0752d
...
...
@@ -16,140 +16,194 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Array
s
;
import
java.util.Array
List
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondition.HeaderExpression
;
/**
* Represents a collection of consumes conditions, typically obtained from {@link org.springframework.web.bind.annotation.RequestMapping#consumes()
* @RequestMapping.consumes()}.
*
* A logical disjunction (' || ') request condition to match requests against consumable media type expressions.
*
* <p>For details on the syntax of the expressions see {@link RequestMapping#consumes()}. If the condition is
* created with 0 consumable media type expressions, it matches to every request.
*
* <p>This request condition is also capable of parsing header expressions specifically selecting 'Content-Type'
* header expressions and converting them to consumable media type expressions.
*
* @author Arjen Poutsma
* @see RequestConditionFactory#parseConsumes(String...)
* @see RequestConditionFactory#parseConsumes(String[], String[])
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
ConsumesRequestCondition
extends
MediaTypesRequestCondition
<
ConsumesRequestCondition
.
ConsumeRequestCondition
>
implements
Comparable
<
ConsumesRequestCondition
>
{
public
class
ConsumesRequestCondition
extends
RequestConditionSupport
<
ConsumesRequestCondition
>
{
ConsumesRequestCondition
(
Collection
<
ConsumeRequestCondition
>
conditions
)
{
super
(
conditions
);
private
final
List
<
ConsumeMediaTypeExpression
>
expressions
;
/**
* Creates a {@link ConsumesRequestCondition} with the given consumable media type expressions.
* @param consumes the expressions to parse; if 0 the condition matches to every request
*/
public
ConsumesRequestCondition
(
String
...
consumes
)
{
this
(
consumes
,
null
);
}
ConsumesRequestCondition
(
String
...
consumes
)
{
this
(
parseConditions
(
Arrays
.
asList
(
consumes
)));
/**
* Creates a {@link ConsumesRequestCondition} with the given header and consumes expressions.
* In addition to consume expressions, {@code "Content-Type"} header expressions are extracted
* and treated as consumable media type expressions.
* @param consumes the consumes expressions to parse; 0 matches to all requests
* @param headers the header expression to parse; 0 matches to all requests
*/
public
ConsumesRequestCondition
(
String
[]
consumes
,
String
[]
headers
)
{
this
(
parseExpressions
(
consumes
,
headers
));
}
private
static
Set
<
ConsumeRequestCondition
>
parseConditions
(
List
<
String
>
consumes
)
{
Set
<
ConsumeRequestCondition
>
conditions
=
new
LinkedHashSet
<
ConsumeRequestCondition
>(
consumes
.
size
());
for
(
String
consume
:
consumes
)
{
conditions
.
add
(
new
ConsumeRequestCondition
(
consume
));
/**
* Private constructor.
*/
private
ConsumesRequestCondition
(
Collection
<
ConsumeMediaTypeExpression
>
expressions
)
{
this
.
expressions
=
new
ArrayList
<
ConsumeMediaTypeExpression
>(
expressions
);
Collections
.
sort
(
this
.
expressions
);
}
private
static
Set
<
ConsumeMediaTypeExpression
>
parseExpressions
(
String
[]
consumes
,
String
[]
headers
)
{
Set
<
ConsumeMediaTypeExpression
>
result
=
new
LinkedHashSet
<
ConsumeMediaTypeExpression
>();
if
(
headers
!=
null
)
{
for
(
String
header
:
headers
)
{
HeaderExpression
expr
=
new
HeaderExpression
(
header
);
if
(
"Content-Type"
.
equalsIgnoreCase
(
expr
.
name
))
{
for
(
MediaType
mediaType
:
MediaType
.
parseMediaTypes
(
expr
.
value
))
{
result
.
add
(
new
ConsumeMediaTypeExpression
(
mediaType
,
expr
.
isNegated
));
}
}
}
}
return
conditions
;
if
(
consumes
!=
null
)
{
for
(
String
consume
:
consumes
)
{
result
.
add
(
new
ConsumeMediaTypeExpression
(
consume
));
}
}
return
result
;
}
/**
* Returns the consumable media types contained in all expressions of this condition.
*/
public
Set
<
MediaType
>
getMediaTypes
()
{
Set
<
MediaType
>
result
=
new
LinkedHashSet
<
MediaType
>();
for
(
ConsumeMediaTypeExpression
expression
:
expressions
)
{
result
.
add
(
expression
.
getMediaType
());
}
return
result
;
}
/**
*
Creates a default set of consumes request condit
ions.
*
Returns true if this condition contains 0 consumable media type express
ions.
*/
public
ConsumesRequestCondition
()
{
this
(
Collections
.<
ConsumeRequestCondition
>
emptySet
());
public
boolean
isEmpty
()
{
return
expressions
.
isEmpty
();
}
@Override
protected
Collection
<
ConsumeMediaTypeExpression
>
getContent
()
{
return
expressions
;
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
false
;
}
/**
* Returns a new {@code RequestCondition} that contains all conditions of this key that match the request.
*
* @param request the request
* @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match
* Returns the "other" instance as long as it contains any expressions; or "this" instance otherwise.
* In other words "other" takes precedence over "this" as long as it has expressions.
* <p>Example: method-level "consumes" overrides type-level "consumes" condition.
*/
public
ConsumesRequestCondition
combine
(
ConsumesRequestCondition
other
)
{
return
!
other
.
expressions
.
isEmpty
()
?
other
:
this
;
}
/**
* Checks if any of the consumable media type expressions match the given request and returns an instance that
* is guaranteed to contain matching media type expressions only.
*
* @param request the current request
*
* @return the same instance if the condition contains no expressions;
* or a new condition with matching expressions; or {@code null} if no expressions match.
*/
public
ConsumesRequestCondition
getMatchingCondition
(
HttpServletRequest
request
)
{
if
(
isEmpty
())
{
return
this
;
}
Set
<
Consume
RequestCondition
>
matchingConditions
=
new
LinkedHashSet
<
ConsumeRequestCondition
>(
getConditions
()
);
for
(
Iterator
<
Consume
RequestCondition
>
iterator
=
matchingConditions
.
iterator
();
iterator
.
hasNext
();)
{
Consume
RequestCondition
condit
ion
=
iterator
.
next
();
if
(!
condit
ion
.
match
(
request
))
{
Set
<
Consume
MediaTypeExpression
>
result
=
new
LinkedHashSet
<
ConsumeMediaTypeExpression
>(
expressions
);
for
(
Iterator
<
Consume
MediaTypeExpression
>
iterator
=
result
.
iterator
();
iterator
.
hasNext
();)
{
Consume
MediaTypeExpression
express
ion
=
iterator
.
next
();
if
(!
express
ion
.
match
(
request
))
{
iterator
.
remove
();
}
}
if
(
matchingConditions
.
isEmpty
())
{
return
null
;
}
else
{
return
new
ConsumesRequestCondition
(
matchingConditions
);
}
return
(
result
.
isEmpty
())
?
null
:
new
ConsumesRequestCondition
(
result
);
}
/**
* Combines this collection of request condition with another. Returns {@code other}, unless it is empty.
*
* @param other the condition to combine with
* Returns:
* <ul>
* <li>0 if the two conditions have the same number of expressions
* <li>Less than 1 if "this" has more in number or more specific consumable media type expressions
* <li>Greater than 1 if "other" has more in number or more specific consumable media type expressions
* </ul>
*
* <p>It is assumed that both instances have been obtained via {@link #getMatchingCondition(HttpServletRequest)}
* and each instance contains the matching consumable media type expression only or is otherwise empty.
*/
public
ConsumesRequestCondition
combine
(
ConsumesRequestCondition
other
)
{
return
!
other
.
isEmpty
()
?
other
:
this
;
}
public
int
compareTo
(
ConsumesRequestCondition
other
)
{
MediaTypeRequestCondition
thisMostSpecificCondition
=
this
.
getMostSpecificCondition
();
MediaTypeRequestCondition
otherMostSpecificCondition
=
other
.
getMostSpecificCondition
();
if
(
thisMostSpecificCondition
==
null
&&
otherMostSpecificCondition
==
null
)
{
public
int
compareTo
(
ConsumesRequestCondition
other
,
HttpServletRequest
request
)
{
if
(
expressions
.
isEmpty
()
&&
other
.
expressions
.
isEmpty
())
{
return
0
;
}
else
if
(
thisMostSpecificCondition
==
null
)
{
else
if
(
expressions
.
isEmpty
()
)
{
return
1
;
}
else
if
(
other
MostSpecificCondition
==
null
)
{
else
if
(
other
.
expressions
.
isEmpty
()
)
{
return
-
1
;
}
else
{
return
thisMostSpecificCondition
.
compareTo
(
otherMostSpecificCondition
);
}
}
private
MediaTypeRequestCondition
getMostSpecificCondition
()
{
if
(!
isEmpty
())
{
return
getSortedConditions
().
get
(
0
);
}
else
{
return
null
;
return
expressions
.
get
(
0
).
compareTo
(
other
.
expressions
.
get
(
0
));
}
}
static
class
ConsumeRequestCondition
extends
MediaTypesRequestCondition
.
MediaTypeRequestCondition
{
/**
* Parsing and request matching logic for consumable media type expressions.
* @see RequestMapping#consumes()
*/
static
class
ConsumeMediaTypeExpression
extends
MediaTypeExpression
{
Consume
RequestCondit
ion
(
String
expression
)
{
Consume
MediaTypeExpress
ion
(
String
expression
)
{
super
(
expression
);
}
Consume
RequestCondit
ion
(
MediaType
mediaType
,
boolean
negated
)
{
Consume
MediaTypeExpress
ion
(
MediaType
mediaType
,
boolean
negated
)
{
super
(
mediaType
,
negated
);
}
@Override
protected
boolean
match
(
HttpServletRequest
request
,
MediaType
mediaType
)
{
MediaType
contentType
=
getContentType
(
request
);
return
mediaType
.
includes
(
contentType
);
}
private
MediaType
getContentType
(
HttpServletRequest
request
)
{
if
(
StringUtils
.
hasLength
(
request
.
getContentType
()))
{
return
MediaType
.
parseMediaType
(
request
.
getContentType
());
}
else
{
return
MediaType
.
APPLICATION_OCTET_STREAM
;
}
MediaType
contentType
=
StringUtils
.
hasLength
(
request
.
getContentType
())
?
MediaType
.
parseMediaType
(
request
.
getContentType
())
:
MediaType
.
APPLICATION_OCTET_STREAM
;
return
mediaType
.
includes
(
contentType
);
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestCondition.java
浏览文件 @
96b0752d
...
...
@@ -16,79 +16,117 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.LinkedHashSet
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.web.bind.annotation.RequestMapping
;
/**
* Represents a collection of header request conditions, typically obtained from {@link
* org.springframework.web.bind.annotation.RequestMapping#headers() @RequestMapping.headers()}.
*
* A logical conjunction (' && ') request condition that matches a request against a set of header expressions.
*
* <p>For details on the syntax of the expressions see {@link RequestMapping#headers()}. If the condition is
* created with 0 header expressions, it will match to every request.
*
* <p>Note: when parsing header expressions, {@code "Accept"} and {@code "Content-Type"} header expressions
* are filtered out. Those should be converted and used as "produces" and "consumes" conditions instead.
* See the constructors for {@link ProducesRequestCondition} and {@link ConsumesRequestCondition}.
*
* @author Arjen Poutsma
* @
see RequestConditionFactory#parseHeaders(String...)
* @
author Rossen Stoyanchev
* @since 3.1
*/
public
class
HeadersRequestCondition
extends
LogicalConjunctionRequestCondition
<
HeadersRequestCondition
.
HeaderRequestCondition
>
implements
Comparable
<
HeadersRequestCondition
>
{
public
class
HeadersRequestCondition
extends
RequestConditionSupport
<
HeadersRequestCondition
>
{
private
final
Set
<
HeaderExpression
>
expressions
;
HeadersRequestCondition
(
Collection
<
HeaderRequestCondition
>
conditions
)
{
super
(
conditions
);
/**
* Create a {@link HeadersRequestCondition} with the given header expressions.
*
* <p>Note: {@code "Accept"} and {@code "Content-Type"} header expressions are filtered out.
* Those should be converted and used as "produces" and "consumes" conditions instead.
* See the constructors for {@link ProducesRequestCondition} and {@link ConsumesRequestCondition}.
*
* @param headers 0 or more header expressions; if 0 the condition will match to every request.
*/
public
HeadersRequestCondition
(
String
...
headers
)
{
this
(
parseExpressions
(
headers
));
}
private
HeadersRequestCondition
(
Collection
<
HeaderExpression
>
conditions
)
{
this
.
expressions
=
Collections
.
unmodifiableSet
(
new
LinkedHashSet
<
HeaderExpression
>(
conditions
));
}
private
static
Collection
<
HeaderExpression
>
parseExpressions
(
String
...
headers
)
{
Set
<
HeaderExpression
>
expressions
=
new
LinkedHashSet
<
HeaderExpression
>();
if
(
headers
!=
null
)
{
for
(
String
header
:
headers
)
{
HeaderExpression
expr
=
new
HeaderExpression
(
header
);
if
(
"Accept"
.
equalsIgnoreCase
(
expr
.
name
)
||
"Content-Type"
.
equalsIgnoreCase
(
expr
.
name
))
{
continue
;
}
expressions
.
add
(
expr
);
}
}
return
expressions
;
}
HeadersRequestCondition
(
String
...
headers
)
{
this
(
parseConditions
(
Arrays
.
asList
(
headers
)));
@Override
protected
Collection
<
HeaderExpression
>
getContent
()
{
return
expressions
;
}
private
static
Set
<
HeaderRequestCondition
>
parseConditions
(
Collection
<
String
>
params
)
{
Set
<
HeaderRequestCondition
>
conditions
=
new
LinkedHashSet
<
HeaderRequestCondition
>(
params
.
size
());
for
(
String
param
:
params
)
{
conditions
.
add
(
new
HeaderRequestCondition
(
param
));
}
return
conditions
;
@Override
protected
boolean
isLogicalConjunction
()
{
return
true
;
}
/**
*
Creates an empty set of header request conditions
.
*
Returns a new instance with the union of the header expressions from "this" and the "other" instance
.
*/
public
HeadersRequestCondition
()
{
this
(
Collections
.<
HeaderRequestCondition
>
emptySet
());
public
HeadersRequestCondition
combine
(
HeadersRequestCondition
other
)
{
Set
<
HeaderExpression
>
set
=
new
LinkedHashSet
<
HeaderExpression
>(
this
.
expressions
);
set
.
addAll
(
other
.
expressions
);
return
new
HeadersRequestCondition
(
set
);
}
/**
* Returns a new {@code RequestCondition} that contains all conditions that match the request.
*
* @param request the request
* @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match
* Returns "this" instance if the request matches to all header expressions; or {@code null} otherwise.
*/
public
HeadersRequestCondition
getMatchingCondition
(
HttpServletRequest
request
)
{
return
match
(
request
)
?
this
:
null
;
for
(
HeaderExpression
expression
:
expressions
)
{
if
(!
expression
.
match
(
request
))
{
return
null
;
}
}
return
this
;
}
/**
* Combines this collection of request condition with another by combining all header request conditions into a
* logical AND.
*
* @param other the condition to combine with
* Returns:
* <ul>
* <li>0 if the two conditions have the same number of header expressions
* <li>Less than 1 if "this" instance has more header expressions
* <li>Greater than 1 if the "other" instance has more header expressions
* </ul>
*
* <p>It is assumed that both instances have been obtained via {@link #getMatchingCondition(HttpServletRequest)}
* and each instance contains the matching header expression only or is otherwise empty.
*/
public
HeadersRequestCondition
combine
(
HeadersRequestCondition
other
)
{
Set
<
HeaderRequestCondition
>
conditions
=
new
LinkedHashSet
<
HeaderRequestCondition
>(
getConditions
());
conditions
.
addAll
(
other
.
getConditions
());
return
new
HeadersRequestCondition
(
conditions
);
}
public
int
compareTo
(
HeadersRequestCondition
other
)
{
return
other
.
getConditions
().
size
()
-
this
.
getConditions
().
size
();
public
int
compareTo
(
HeadersRequestCondition
other
,
HttpServletRequest
request
)
{
return
other
.
expressions
.
size
()
-
this
.
expressions
.
size
();
}
static
class
HeaderRequestCondition
extends
AbstractNameValueCondition
<
String
>
{
/**
* Parsing and request matching logic for header expressions.
* @see RequestMapping#headers()
*/
static
class
HeaderExpression
extends
AbstractNameValueExpression
<
String
>
{
public
Header
RequestCondit
ion
(
String
expression
)
{
public
Header
Express
ion
(
String
expression
)
{
super
(
expression
);
}
...
...
@@ -107,20 +145,6 @@ public class HeadersRequestCondition
return
value
.
equals
(
request
.
getHeader
(
name
));
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
!=
null
&&
obj
instanceof
HeaderRequestCondition
)
{
HeaderRequestCondition
other
=
(
HeaderRequestCondition
)
obj
;
return
((
this
.
name
.
equalsIgnoreCase
(
other
.
name
))
&&
(
this
.
value
!=
null
?
this
.
value
.
equals
(
other
.
value
)
:
other
.
value
==
null
)
&&
this
.
isNegated
==
other
.
isNegated
);
}
return
false
;
}
@Override
public
int
hashCode
()
{
int
result
=
name
.
toLowerCase
().
hashCode
();
...
...
@@ -128,7 +152,5 @@ public class HeadersRequestCondition
result
=
31
*
result
+
(
isNegated
?
1
:
0
);
return
result
;
}
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalConjunctionRequestCondition.java
已删除
100644 → 0
浏览文件 @
3a332e55
/*
* Copyright 2002-2011 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Collection
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
/**
* {@link RequestCondition} implementation that represents a logical AND (i.e. &&).
*
* @author Arjen Poutsma
* @since 3.1
*/
class
LogicalConjunctionRequestCondition
<
T
extends
RequestCondition
>
extends
RequestConditionComposite
<
T
>
{
LogicalConjunctionRequestCondition
(
Collection
<
T
>
conditions
)
{
super
(
conditions
);
}
public
boolean
match
(
HttpServletRequest
request
)
{
Set
<
T
>
conditions
=
getConditions
();
if
(
isEmpty
())
{
return
true
;
}
for
(
T
condition
:
conditions
)
{
if
(!
condition
.
match
(
request
))
{
return
false
;
}
}
return
true
;
}
@Override
protected
String
getToStringInfix
()
{
return
" && "
;
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/
LogicalDisjunctionRequestCondit
ion.java
→
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/
MediaTypeExpress
ion.java
浏览文件 @
96b0752d
...
...
@@ -16,36 +16,81 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Collection
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.http.MediaType
;
import
org.springframework.web.bind.annotation.RequestMapping
;
/**
* {@link RequestCondition} implementation that represents a logical OR (i.e. ||).
*
* Supports media type expressions as described in:
* {@link RequestMapping#consumes()} and {@link RequestMapping#produces()}.
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @since 3.1
*/
class
LogicalDisjunctionRequestCondition
<
T
extends
RequestCondition
>
extends
RequestConditionComposite
<
T
>
{
abstract
class
MediaTypeExpression
implements
Comparable
<
MediaTypeExpression
>
{
private
final
MediaType
mediaType
;
private
final
boolean
isNegated
;
MediaTypeExpression
(
String
expression
)
{
if
(
expression
.
startsWith
(
"!"
))
{
isNegated
=
true
;
expression
=
expression
.
substring
(
1
);
}
else
{
isNegated
=
false
;
}
this
.
mediaType
=
MediaType
.
parseMediaType
(
expression
);
}
LogicalDisjunctionRequestCondition
(
Collection
<
T
>
conditions
)
{
super
(
conditions
);
MediaTypeExpression
(
MediaType
mediaType
,
boolean
negated
)
{
this
.
mediaType
=
mediaType
;
isNegated
=
negated
;
}
public
boolean
match
(
HttpServletRequest
request
)
{
if
(
isEmpty
())
{
boolean
match
=
match
(
request
,
this
.
mediaType
);
return
!
isNegated
?
match
:
!
match
;
}
protected
abstract
boolean
match
(
HttpServletRequest
request
,
MediaType
mediaType
);
MediaType
getMediaType
()
{
return
mediaType
;
}
public
int
compareTo
(
MediaTypeExpression
other
)
{
return
MediaType
.
SPECIFICITY_COMPARATOR
.
compare
(
this
.
getMediaType
(),
other
.
getMediaType
());
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
for
(
RequestCondition
condition
:
getConditions
())
{
if
(
condition
.
match
(
request
))
{
return
true
;
}
if
(
obj
!=
null
&&
getClass
().
equals
(
obj
.
getClass
()))
{
MediaTypeExpression
other
=
(
MediaTypeExpression
)
obj
;
return
(
this
.
mediaType
.
equals
(
other
.
mediaType
))
&&
(
this
.
isNegated
==
other
.
isNegated
);
}
return
false
;
}
@Override
protected
String
getToStringInfix
()
{
return
" || "
;
public
int
hashCode
()
{
return
mediaType
.
hashCode
();
}
@Override
public
String
toString
()
{
StringBuilder
builder
=
new
StringBuilder
();
if
(
isNegated
)
{
builder
.
append
(
'!'
);
}
builder
.
append
(
mediaType
.
toString
());
return
builder
.
toString
();
}
}
}
\ No newline at end of file
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/MediaTypesRequestCondition.java
已删除
100644 → 0
浏览文件 @
3a332e55
/*
* Copyright 2002-2011 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.http.MediaType
;
/**
* @author Arjen Poutsma
*/
class
MediaTypesRequestCondition
<
T
extends
MediaTypesRequestCondition
.
MediaTypeRequestCondition
>
extends
LogicalDisjunctionRequestCondition
<
T
>
{
private
final
List
<
T
>
sortedConditions
;
public
MediaTypesRequestCondition
(
Collection
<
T
>
conditions
)
{
super
(
conditions
);
sortedConditions
=
new
ArrayList
<
T
>(
conditions
);
Collections
.
sort
(
sortedConditions
);
}
protected
List
<
T
>
getSortedConditions
()
{
return
sortedConditions
;
}
/**
* Returns all {@link MediaType}s contained in this condition.
*/
public
Set
<
MediaType
>
getMediaTypes
()
{
Set
<
MediaType
>
result
=
new
LinkedHashSet
<
MediaType
>();
for
(
MediaTypeRequestCondition
condition
:
getConditions
())
{
result
.
add
(
condition
.
getMediaType
());
}
return
result
;
}
/**
* @author Arjen Poutsma
*/
protected
abstract
static
class
MediaTypeRequestCondition
implements
RequestCondition
,
Comparable
<
MediaTypeRequestCondition
>
{
private
final
MediaType
mediaType
;
private
final
boolean
isNegated
;
MediaTypeRequestCondition
(
MediaType
mediaType
,
boolean
negated
)
{
this
.
mediaType
=
mediaType
;
isNegated
=
negated
;
}
MediaTypeRequestCondition
(
String
expression
)
{
if
(
expression
.
startsWith
(
"!"
))
{
isNegated
=
true
;
expression
=
expression
.
substring
(
1
);
}
else
{
isNegated
=
false
;
}
this
.
mediaType
=
MediaType
.
parseMediaType
(
expression
);
}
public
boolean
match
(
HttpServletRequest
request
)
{
boolean
match
=
match
(
request
,
this
.
mediaType
);
return
!
isNegated
?
match
:
!
match
;
}
protected
abstract
boolean
match
(
HttpServletRequest
request
,
MediaType
mediaType
);
MediaType
getMediaType
()
{
return
mediaType
;
}
public
int
compareTo
(
MediaTypeRequestCondition
other
)
{
return
MediaType
.
SPECIFICITY_COMPARATOR
.
compare
(
this
.
getMediaType
(),
other
.
getMediaType
());
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
!=
null
&&
getClass
().
equals
(
obj
.
getClass
()))
{
MediaTypeRequestCondition
other
=
(
MediaTypeRequestCondition
)
obj
;
return
(
this
.
mediaType
.
equals
(
other
.
mediaType
))
&&
(
this
.
isNegated
==
other
.
isNegated
);
}
return
false
;
}
@Override
public
int
hashCode
()
{
return
mediaType
.
hashCode
();
}
@Override
public
String
toString
()
{
StringBuilder
builder
=
new
StringBuilder
();
if
(
isNegated
)
{
builder
.
append
(
'!'
);
}
builder
.
append
(
mediaType
.
toString
());
return
builder
.
toString
();
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestCondition.java
浏览文件 @
96b0752d
...
...
@@ -16,80 +16,106 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.util.WebUtils
;
/**
* Represents a collection of parameter request conditions, typically obtained from {@link
* org.springframework.web.bind.annotation.RequestMapping#params() @RequestMapping.params()}.
*
* A logical conjunction (' && ') request condition that matches a request against a set parameter expressions.
*
* <p>For details on the syntax of the expressions see {@link RequestMapping#params()}. If the condition is
* created with 0 parameter expressions, it will match to every request.
*
* @author Arjen Poutsma
* @
see RequestConditionFactory#parseParams(String...)
* @
author Rossen Stoyanchev
* @since 3.1
*/
public
class
ParamsRequestCondition
extends
LogicalConjunctionRequestCondition
<
ParamsRequestCondition
.
ParamRequestCondition
>
implements
Comparable
<
ParamsRequestCondition
>
{
public
class
ParamsRequestCondition
extends
RequestConditionSupport
<
ParamsRequestCondition
>
{
private
ParamsRequestCondition
(
Collection
<
ParamRequestCondition
>
conditions
)
{
super
(
conditions
);
private
final
Set
<
ParamExpression
>
expressions
;
/**
* Create a {@link ParamsRequestCondition} with the given param expressions.
*
* @param params 0 or more param expressions; if 0 the condition will match to every request.
*/
public
ParamsRequestCondition
(
String
...
params
)
{
this
(
parseExpressions
(
params
));
}
ParamsRequestCondition
(
String
...
param
s
)
{
this
(
parseConditions
(
Arrays
.
asList
(
params
)
));
private
ParamsRequestCondition
(
Collection
<
ParamExpression
>
condition
s
)
{
this
.
expressions
=
Collections
.
unmodifiableSet
(
new
LinkedHashSet
<
ParamExpression
>(
conditions
));
}
private
static
Set
<
ParamRequestCondition
>
parseConditions
(
List
<
String
>
params
)
{
Set
<
ParamRequestCondition
>
conditions
=
new
LinkedHashSet
<
ParamRequestCondition
>(
params
.
size
());
for
(
String
param
:
params
)
{
conditions
.
add
(
new
ParamRequestCondition
(
param
));
private
static
Collection
<
ParamExpression
>
parseExpressions
(
String
...
params
)
{
Set
<
ParamExpression
>
expressions
=
new
LinkedHashSet
<
ParamExpression
>();
if
(
params
!=
null
)
{
for
(
String
header
:
params
)
{
expressions
.
add
(
new
ParamExpression
(
header
));
}
}
return
conditions
;
return
expressions
;
}
@Override
protected
Collection
<
ParamExpression
>
getContent
()
{
return
expressions
;
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
true
;
}
/**
*
Creates an empty set of parameter request conditions
.
*
Returns a new instance with the union of the param expressions from "this" and the "other" instance
.
*/
public
ParamsRequestCondition
()
{
this
(
Collections
.<
ParamRequestCondition
>
emptySet
());
public
ParamsRequestCondition
combine
(
ParamsRequestCondition
other
)
{
Set
<
ParamExpression
>
set
=
new
LinkedHashSet
<
ParamExpression
>(
this
.
expressions
);
set
.
addAll
(
other
.
expressions
);
return
new
ParamsRequestCondition
(
set
);
}
/**
* Returns a new {@code RequestCondition} that contains all conditions that match the request.
*
* @param request the request
* @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match
* Returns "this" instance if the request matches to all parameter expressions; or {@code null} otherwise.
*/
public
ParamsRequestCondition
getMatchingCondition
(
HttpServletRequest
request
)
{
return
match
(
request
)
?
this
:
null
;
for
(
ParamExpression
expression
:
expressions
)
{
if
(!
expression
.
match
(
request
))
{
return
null
;
}
}
return
this
;
}
/**
* Combines this collection of request condition with another by combining all parameter request conditions into a
* logical AND.
*
* @param other the condition to combine with
* Returns:
* <ul>
* <li>0 if the two conditions have the same number of parameter expressions
* <li>Less than 1 if "this" instance has more parameter expressions
* <li>Greater than 1 if the "other" instance has more parameter expressions
* </ul>
*
* <p>It is assumed that both instances have been obtained via {@link #getMatchingCondition(HttpServletRequest)}
* and each instance contains the matching parameter expressions only or is otherwise empty.
*/
public
ParamsRequestCondition
combine
(
ParamsRequestCondition
other
)
{
Set
<
ParamRequestCondition
>
conditions
=
new
LinkedHashSet
<
ParamRequestCondition
>(
getConditions
());
conditions
.
addAll
(
other
.
getConditions
());
return
new
ParamsRequestCondition
(
conditions
);
}
public
int
compareTo
(
ParamsRequestCondition
other
)
{
return
other
.
getConditions
().
size
()
-
this
.
getConditions
().
size
();
public
int
compareTo
(
ParamsRequestCondition
other
,
HttpServletRequest
request
)
{
return
other
.
expressions
.
size
()
-
this
.
expressions
.
size
();
}
static
class
ParamRequestCondition
extends
AbstractNameValueCondition
<
String
>
{
/**
* Parsing and request matching logic for parameter expressions.
* @see RequestMapping#params()
*/
static
class
ParamExpression
extends
AbstractNameValueExpression
<
String
>
{
Param
RequestCondit
ion
(
String
expression
)
{
Param
Express
ion
(
String
expression
)
{
super
(
expression
);
}
...
...
@@ -107,20 +133,6 @@ public class ParamsRequestCondition
protected
boolean
matchValue
(
HttpServletRequest
request
)
{
return
value
.
equals
(
request
.
getParameter
(
name
));
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
!=
null
&&
obj
instanceof
ParamRequestCondition
)
{
ParamRequestCondition
other
=
(
ParamRequestCondition
)
obj
;
return
((
this
.
name
.
equals
(
other
.
name
))
&&
(
this
.
value
!=
null
?
this
.
value
.
equals
(
other
.
value
)
:
other
.
value
==
null
)
&&
this
.
isNegated
==
other
.
isNegated
);
}
return
false
;
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/PatternsRequestCondition.java
0 → 100644
浏览文件 @
96b0752d
/*
* Copyright 2002-2011 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.util.AntPathMatcher
;
import
org.springframework.util.PathMatcher
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.util.UrlPathHelper
;
/**
* A logical disjunction (' || ') request condition that matches a request against a set of URL path patterns.
*
* <p>See Javadoc on individual methods for details on how URL patterns are matched, combined, and compared.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
PatternsRequestCondition
extends
RequestConditionSupport
<
PatternsRequestCondition
>
{
private
final
Set
<
String
>
patterns
;
private
final
UrlPathHelper
urlPathHelper
;
private
final
PathMatcher
pathMatcher
;
/**
* Creates a new {@link PatternsRequestCondition} with the given URL patterns.
* Each pattern that is not empty and does not start with "/" is prepended with "/".
* @param patterns 0 or more URL patterns; if 0 the condition will match to every request.
*/
public
PatternsRequestCondition
(
String
...
patterns
)
{
this
(
patterns
,
new
UrlPathHelper
(),
new
AntPathMatcher
());
}
/**
* Creates a new {@link PatternsRequestCondition} with the given URL patterns.
* Each pattern that is not empty and does not start with "/" is prepended with "/".
*
* @param patterns the URL patterns to use; if 0 the condition will match to every request.
* @param urlPathHelper a {@link UrlPathHelper} for determining the lookup path for a request
* @param pathMatcher a {@link PathMatcher} for pattern path matching
*/
public
PatternsRequestCondition
(
String
[]
patterns
,
UrlPathHelper
urlPathHelper
,
PathMatcher
pathMatcher
)
{
this
(
asList
(
patterns
),
urlPathHelper
,
pathMatcher
);
}
private
static
List
<
String
>
asList
(
String
...
patterns
)
{
return
patterns
!=
null
?
Arrays
.
asList
(
patterns
)
:
Collections
.<
String
>
emptyList
();
}
/**
* Private constructor.
*/
private
PatternsRequestCondition
(
Collection
<
String
>
patterns
,
UrlPathHelper
urlPathHelper
,
PathMatcher
pathMatcher
)
{
this
.
patterns
=
Collections
.
unmodifiableSet
(
prependLeadingSlash
(
patterns
));
this
.
urlPathHelper
=
urlPathHelper
;
this
.
pathMatcher
=
pathMatcher
;
}
private
static
Set
<
String
>
prependLeadingSlash
(
Collection
<
String
>
patterns
)
{
if
(
patterns
==
null
)
{
return
Collections
.
emptySet
();
}
Set
<
String
>
result
=
new
LinkedHashSet
<
String
>(
patterns
.
size
());
for
(
String
pattern
:
patterns
)
{
if
(
StringUtils
.
hasLength
(
pattern
)
&&
!
pattern
.
startsWith
(
"/"
))
{
pattern
=
"/"
+
pattern
;
}
result
.
add
(
pattern
);
}
return
result
;
}
public
Set
<
String
>
getPatterns
()
{
return
patterns
;
}
@Override
protected
Collection
<
String
>
getContent
()
{
return
patterns
;
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
false
;
}
/**
* Returns a new instance with URL patterns from the current instance ("this") and
* the "other" instance as follows:
* <ul>
* <li>If there are patterns in both instances, combine the patterns in "this" with
* the patterns in "other" using {@link PathMatcher#combine(String, String)}.
* <li>If only one instance has patterns, use them.
* <li>If neither instance has patterns, use "".
* </ul>
*/
public
PatternsRequestCondition
combine
(
PatternsRequestCondition
other
)
{
Set
<
String
>
result
=
new
LinkedHashSet
<
String
>();
if
(!
this
.
patterns
.
isEmpty
()
&&
!
other
.
patterns
.
isEmpty
())
{
for
(
String
pattern1
:
this
.
patterns
)
{
for
(
String
pattern2
:
other
.
patterns
)
{
result
.
add
(
pathMatcher
.
combine
(
pattern1
,
pattern2
));
}
}
}
else
if
(!
this
.
patterns
.
isEmpty
())
{
result
.
addAll
(
this
.
patterns
);
}
else
if
(!
other
.
patterns
.
isEmpty
())
{
result
.
addAll
(
other
.
patterns
);
}
else
{
result
.
add
(
""
);
}
return
new
PatternsRequestCondition
(
result
,
urlPathHelper
,
pathMatcher
);
}
/**
* Checks if any of the patterns match the given request and returns an instance that is guaranteed
* to contain matching patterns, sorted via {@link PathMatcher#getPatternComparator(String)}.
*
* <p>A matching pattern is obtained by making checks in the following order:
* <ul>
* <li>Direct match
* <li>A pattern match with ".*" appended assuming the pattern already doesn't contain "."
* <li>A pattern match
* <li>A pattern match with "/" appended assuming the patterns already end with "/"
* </ul>
*
* @param request the current request
*
* @return the same instance if the condition contains no patterns;
* or a new condition with sorted matching patterns; or {@code null} if no patterns match.
*/
public
PatternsRequestCondition
getMatchingCondition
(
HttpServletRequest
request
)
{
if
(
patterns
.
isEmpty
())
{
return
this
;
}
String
lookupPath
=
urlPathHelper
.
getLookupPathForRequest
(
request
);
List
<
String
>
matches
=
new
ArrayList
<
String
>();
for
(
String
pattern
:
patterns
)
{
String
match
=
getMatchingPattern
(
pattern
,
lookupPath
);
if
(
match
!=
null
)
{
matches
.
add
(
match
);
}
}
Collections
.
sort
(
matches
,
pathMatcher
.
getPatternComparator
(
lookupPath
));
return
matches
.
isEmpty
()
?
null
:
new
PatternsRequestCondition
(
matches
,
urlPathHelper
,
pathMatcher
);
}
private
String
getMatchingPattern
(
String
pattern
,
String
lookupPath
)
{
if
(
pattern
.
equals
(
lookupPath
))
{
return
pattern
;
}
boolean
hasSuffix
=
pattern
.
indexOf
(
'.'
)
!=
-
1
;
if
(!
hasSuffix
&&
pathMatcher
.
match
(
pattern
+
".*"
,
lookupPath
))
{
return
pattern
+
".*"
;
}
if
(
pathMatcher
.
match
(
pattern
,
lookupPath
))
{
return
pattern
;
}
boolean
endsWithSlash
=
pattern
.
endsWith
(
"/"
);
if
(!
endsWithSlash
&&
pathMatcher
.
match
(
pattern
+
"/"
,
lookupPath
))
{
return
pattern
+
"/"
;
}
return
null
;
}
/**
* Compare the two conditions and return 0 if they match equally to the request, less than one if "this"
* matches the request more, and greater than one if "other" matches the request more. Patterns are
* compared one at a time, from top to bottom via {@link PathMatcher#getPatternComparator(String)}.
* If all compared patterns match equally, but one instance has more patterns, it is a closer match.
*
* <p>It is assumed that both instances have been obtained via {@link #getMatchingCondition(HttpServletRequest)}
* to ensure they contain only patterns that match the request and are sorted with the best matches on top.
*/
public
int
compareTo
(
PatternsRequestCondition
other
,
HttpServletRequest
request
)
{
String
lookupPath
=
urlPathHelper
.
getLookupPathForRequest
(
request
);
Comparator
<
String
>
patternComparator
=
pathMatcher
.
getPatternComparator
(
lookupPath
);
Iterator
<
String
>
iterator
=
patterns
.
iterator
();
Iterator
<
String
>
iteratorOther
=
other
.
patterns
.
iterator
();
while
(
iterator
.
hasNext
()
&&
iteratorOther
.
hasNext
())
{
int
result
=
patternComparator
.
compare
(
iterator
.
next
(),
iteratorOther
.
next
());
if
(
result
!=
0
)
{
return
result
;
}
}
if
(
iterator
.
hasNext
())
{
return
-
1
;
}
else
if
(
iteratorOther
.
hasNext
())
{
return
1
;
}
else
{
return
0
;
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ProducesRequestCondition.java
浏览文件 @
96b0752d
...
...
@@ -16,99 +16,170 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Array
s
;
import
java.util.Array
List
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondition.HeaderExpression
;
/**
* Represents a collection of produces conditions, typically obtained from {@link
* org.springframework.web.bind.annotation.RequestMapping#produces() @RequestMapping.produces()}.
*
* A logical disjunction (' || ') request condition to match requests against producible media type expressions.
*
* <p>For details on the syntax of the expressions see {@link RequestMapping#consumes()}. If the condition is
* created with 0 producible media type expressions, it matches to every request.
*
* <p>This request condition is also capable of parsing header expressions specifically selecting 'Accept' header
* expressions and converting them to prodicuble media type expressions.
*
* @author Arjen Poutsma
* @see RequestConditionFactory#parseProduces(String...)
* @see RequestConditionFactory#parseProduces(String[], String[])
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
ProducesRequestCondition
extends
MediaTypesRequestCondition
<
ProducesRequestCondition
.
ProduceRequestCondition
>
{
public
class
ProducesRequestCondition
extends
RequestConditionSupport
<
ProducesRequestCondition
>
{
private
final
List
<
ProduceMediaTypeExpression
>
expressions
;
ProducesRequestCondition
(
Collection
<
ProduceRequestCondition
>
conditions
)
{
super
(
conditions
);
/**
* Creates a {@link ProducesRequestCondition} with the given producible media type expressions.
* @param produces the expressions to parse; if 0 the condition matches to every request
*/
public
ProducesRequestCondition
(
String
...
produces
)
{
this
(
produces
,
null
);
}
/**
* Creates a {@link ProducesRequestCondition} with the given header and produces expressions.
* In addition to produces expressions, {@code "Accept"} header expressions are extracted and treated as
* producible media type expressions.
* @param produces the produces expressions to parse
* @param headers the header expression to parse
*/
public
ProducesRequestCondition
(
String
[]
produces
,
String
[]
headers
)
{
this
(
parseExpressions
(
produces
,
headers
));
}
/**
* A private constructor.
*/
private
ProducesRequestCondition
(
Collection
<
ProduceMediaTypeExpression
>
expressions
)
{
this
.
expressions
=
new
ArrayList
<
ProduceMediaTypeExpression
>(
expressions
);
Collections
.
sort
(
this
.
expressions
);
}
ProducesRequestCondition
(
String
...
consumes
)
{
this
(
parseConditions
(
Arrays
.
asList
(
consumes
)));
private
static
Set
<
ProduceMediaTypeExpression
>
parseExpressions
(
String
[]
produces
,
String
[]
headers
)
{
Set
<
ProduceMediaTypeExpression
>
result
=
new
LinkedHashSet
<
ProduceMediaTypeExpression
>();
if
(
headers
!=
null
)
{
for
(
String
header
:
headers
)
{
HeaderExpression
expr
=
new
HeaderExpression
(
header
);
if
(
"Accept"
.
equalsIgnoreCase
(
expr
.
name
))
{
for
(
MediaType
mediaType
:
MediaType
.
parseMediaTypes
(
expr
.
value
))
{
result
.
add
(
new
ProduceMediaTypeExpression
(
mediaType
,
expr
.
isNegated
));
}
}
}
}
if
(
produces
!=
null
)
{
for
(
String
produce
:
produces
)
{
result
.
add
(
new
ProduceMediaTypeExpression
(
produce
));
}
}
return
result
;
}
private
static
Set
<
ProduceRequestCondition
>
parseConditions
(
List
<
String
>
consumes
)
{
Set
<
ProduceRequestCondition
>
conditions
=
new
LinkedHashSet
<
ProduceRequestCondition
>(
consumes
.
size
());
for
(
String
consume
:
consumes
)
{
conditions
.
add
(
new
ProduceRequestCondition
(
consume
));
/**
* Returns the producible media types contained in all expressions of this condition.
*/
public
Set
<
MediaType
>
getMediaTypes
()
{
Set
<
MediaType
>
result
=
new
LinkedHashSet
<
MediaType
>();
for
(
ProduceMediaTypeExpression
expression
:
expressions
)
{
result
.
add
(
expression
.
getMediaType
());
}
return
conditions
;
return
result
;
}
/**
*
Creates an empty set of consumes request condit
ions.
*
Returns true if this condition contains no producible media type express
ions.
*/
public
ProducesRequestCondition
()
{
this
(
Collections
.<
ProduceRequestCondition
>
emptySet
());
public
boolean
isEmpty
()
{
return
expressions
.
isEmpty
();
}
@Override
protected
Collection
<
ProduceMediaTypeExpression
>
getContent
()
{
return
expressions
;
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
false
;
}
/**
* Returns the "other" instance if "other" as long as it contains any expressions; or "this" instance otherwise.
* In other words "other" takes precedence over "this" as long as it contains any expressions.
* <p>Example: method-level "produces" overrides type-level "produces" condition.
*/
public
ProducesRequestCondition
combine
(
ProducesRequestCondition
other
)
{
return
!
other
.
expressions
.
isEmpty
()
?
other
:
this
;
}
/**
* Returns a new {@code RequestCondition} that contains all conditions of this key that match the request.
*
* @param request the request
* @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match
* Checks if any of the producible media type expressions match the given request and returns an instance that
* is guaranteed to contain matching media type expressions only.
*
* @param request the current request
*
* @return the same instance if the condition contains no expressions;
* or a new condition with matching expressions; or {@code null} if no expressions match.
*/
public
ProducesRequestCondition
getMatchingCondition
(
HttpServletRequest
request
)
{
if
(
isEmpty
())
{
return
this
;
}
Set
<
Produce
RequestCondition
>
matchingConditions
=
new
LinkedHashSet
<
ProduceRequestCondition
>(
getConditions
()
);
for
(
Iterator
<
Produce
RequestCondition
>
iterator
=
matchingConditions
.
iterator
();
iterator
.
hasNext
();)
{
Produce
RequestCondition
condit
ion
=
iterator
.
next
();
if
(!
condit
ion
.
match
(
request
))
{
Set
<
Produce
MediaTypeExpression
>
result
=
new
LinkedHashSet
<
ProduceMediaTypeExpression
>(
expressions
);
for
(
Iterator
<
Produce
MediaTypeExpression
>
iterator
=
result
.
iterator
();
iterator
.
hasNext
();)
{
Produce
MediaTypeExpression
express
ion
=
iterator
.
next
();
if
(!
express
ion
.
match
(
request
))
{
iterator
.
remove
();
}
}
if
(
matchingConditions
.
isEmpty
())
{
return
null
;
}
else
{
return
new
ProducesRequestCondition
(
matchingConditions
);
}
return
(
result
.
isEmpty
())
?
null
:
new
ProducesRequestCondition
(
result
);
}
/**
* Combines this collection of request condition with another. Returns {@code other}, unless it has the default
* value (i.e. {@code */*}).
*
* @param other the condition to combine with
* Returns:
* <ul>
* <li>0 if the two conditions have the same number of expressions
* <li>Less than 1 if "this" has more in number or more specific producible media type expressions
* <li>Greater than 1 if "other" has more in number or more specific producible media type expressions
* </ul>
*
* <p>It is assumed that both instances have been obtained via {@link #getMatchingCondition(HttpServletRequest)}
* and each instance contains the matching producible media type expression only or is otherwise empty.
*/
public
ProducesRequestCondition
combine
(
ProducesRequestCondition
other
)
{
return
!
other
.
isEmpty
()
?
other
:
this
;
}
public
int
compareTo
(
ProducesRequestCondition
other
,
List
<
MediaType
>
acceptedMediaTypes
)
{
public
int
compareTo
(
ProducesRequestCondition
other
,
HttpServletRequest
request
)
{
String
acceptHeader
=
request
.
getHeader
(
"Accept"
)
;
List
<
MediaType
>
acceptedMediaTypes
=
MediaType
.
parseMediaTypes
(
acceptHeader
);
MediaType
.
sortByQualityValue
(
acceptedMediaTypes
);
for
(
MediaType
acceptedMediaType
:
acceptedMediaTypes
)
{
int
thisIndex
=
this
.
indexOfMediaType
(
acceptedMediaType
);
int
otherIndex
=
other
.
indexOfMediaType
(
acceptedMediaType
);
if
(
thisIndex
!=
otherIndex
)
{
return
otherIndex
-
thisIndex
;
}
else
if
(
thisIndex
!=
-
1
&&
otherIndex
!=
-
1
)
{
Produce
RequestCondition
thisCondition
=
this
.
getSortedConditions
()
.
get
(
thisIndex
);
Produce
RequestCondition
otherCondition
=
other
.
getSortedConditions
()
.
get
(
otherIndex
);
int
result
=
this
Condition
.
compareTo
(
otherCondition
);
Produce
MediaTypeExpression
thisExpr
=
this
.
expressions
.
get
(
thisIndex
);
Produce
MediaTypeExpression
otherExpr
=
other
.
expressions
.
get
(
otherIndex
);
int
result
=
this
Expr
.
compareTo
(
otherExpr
);
if
(
result
!=
0
)
{
return
result
;
}
...
...
@@ -118,29 +189,31 @@ public class ProducesRequestCondition
}
private
int
indexOfMediaType
(
MediaType
mediaType
)
{
List
<
ProduceRequestCondition
>
sortedConditions
=
getSortedConditions
();
for
(
int
i
=
0
;
i
<
sortedConditions
.
size
();
i
++)
{
ProduceRequestCondition
condition
=
sortedConditions
.
get
(
i
);
if
(
mediaType
.
includes
(
condition
.
getMediaType
()))
{
for
(
int
i
=
0
;
i
<
expressions
.
size
();
i
++)
{
if
(
mediaType
.
includes
(
expressions
.
get
(
i
).
getMediaType
()))
{
return
i
;
}
}
return
-
1
;
}
static
class
ProduceRequestCondition
extends
MediaTypesRequestCondition
.
MediaTypeRequestCondition
{
/**
* Parsing and request matching logic for producible media type expressions.
* @see RequestMapping#produces()
*/
static
class
ProduceMediaTypeExpression
extends
MediaTypeExpression
{
Produce
RequestCondit
ion
(
MediaType
mediaType
,
boolean
negated
)
{
Produce
MediaTypeExpress
ion
(
MediaType
mediaType
,
boolean
negated
)
{
super
(
mediaType
,
negated
);
}
Produce
RequestCondit
ion
(
String
expression
)
{
Produce
MediaTypeExpress
ion
(
String
expression
)
{
super
(
expression
);
}
@Override
protected
boolean
match
(
HttpServletRequest
request
,
MediaType
mediaType
)
{
List
<
MediaType
>
acceptedMediaTypes
=
getAccept
(
request
);
List
<
MediaType
>
acceptedMediaTypes
=
getAccept
edMediaTypes
(
request
);
for
(
MediaType
acceptedMediaType
:
acceptedMediaTypes
)
{
if
(
mediaType
.
isCompatibleWith
(
acceptedMediaType
))
{
return
true
;
...
...
@@ -149,7 +222,7 @@ public class ProducesRequestCondition
return
false
;
}
private
List
<
MediaType
>
getAccept
(
HttpServletRequest
request
)
{
private
List
<
MediaType
>
getAccept
edMediaTypes
(
HttpServletRequest
request
)
{
String
acceptHeader
=
request
.
getHeader
(
"Accept"
);
if
(
StringUtils
.
hasLength
(
acceptHeader
))
{
return
MediaType
.
parseMediaTypes
(
acceptHeader
);
...
...
@@ -159,4 +232,5 @@ public class ProducesRequestCondition
}
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition.java
浏览文件 @
96b0752d
...
...
@@ -19,23 +19,39 @@ package org.springframework.web.servlet.mvc.method.condition;
import
javax.servlet.http.HttpServletRequest
;
/**
* Defines the contract for conditions that must be met given an incoming request.
*
* <p>Implementations of this interface are created by the {@link RequestConditionFactory}.
*
* The contract for request conditions.
*
* <p>Request conditions can be combined (e.g. type + method-level conditions), matched to a request,
* or compared to each other to determine if one matches the request better.
*
* @author Rossen Stoyanchev
* @author Arjen Poutsma
* @see RequestConditionFactory
* @since 3.1
*/
public
interface
RequestCondition
{
public
interface
RequestCondition
<
This
extends
RequestCondition
<
This
>>
{
/**
*
Indicates whether this condition matches against the given servlet request
.
*
*
@param request the request
* @return
{@code true} if this condition matches the request; {@code false} otherwise
*
Defines the rules for combining "this" condition (i.e. the current instance) with another condition
.
*
<p>Example: combine type- and method-level request mapping conditions.
*
* @return
s a request condition instance that is the result of combining the two condition instances.
*/
boolean
match
(
HttpServletRequest
request
);
This
combine
(
This
other
);
/**
* Checks if this condition matches the provided request and returns a potentially new request condition
* with content tailored to the current request. For example a condition with URL patterns might return
* a new condition that contains matching patterns sorted with best matching patterns on top.
*
* @return a condition instance in case of a match; or {@code null} if there is no match.
*/
This
getMatchingCondition
(
HttpServletRequest
request
);
/**
* Compares "this" condition (i.e. the current instance) with another condition in the context of a request.
* <p>Note: it is assumed instances have been obtained via {@link #getMatchingCondition(HttpServletRequest)}
* to ensure they have content relevant to current request only.
*/
int
compareTo
(
This
other
,
HttpServletRequest
request
);
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionFactory.java
已删除
100644 → 0
浏览文件 @
3a332e55
/*
* Copyright 2002-2011 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Set
;
import
org.springframework.http.MediaType
;
import
org.springframework.web.bind.annotation.RequestMethod
;
/**
* Factory for {@link RequestCondition} objects.
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @since 3.1
*/
public
abstract
class
RequestConditionFactory
{
private
static
final
String
CONTENT_TYPE_HEADER
=
"Content-Type"
;
private
static
final
String
ACCEPT_HEADER
=
"Accept"
;
/**
* Parses the given request methods, and returns them as a single request condition.
*
* @param methods the methods
* @return the request condition
* @see org.springframework.web.bind.annotation.RequestMapping#method()
*/
public
static
RequestMethodsRequestCondition
parseMethods
(
RequestMethod
...
methods
)
{
return
methods
!=
null
?
new
RequestMethodsRequestCondition
(
methods
)
:
new
RequestMethodsRequestCondition
();
}
/**
* Parses the given parameters, and returns them as a single request condition.
*
* @param params the parameters
* @return the request condition
* @see org.springframework.web.bind.annotation.RequestMapping#params()
*/
public
static
ParamsRequestCondition
parseParams
(
String
...
params
)
{
return
params
!=
null
?
new
ParamsRequestCondition
(
params
)
:
new
ParamsRequestCondition
();
}
/**
* Parses the given headers, and returns them as a single request condition.
*
* @param headers the headers
* @return the request condition
* @see org.springframework.web.bind.annotation.RequestMapping#headers()
*/
public
static
HeadersRequestCondition
parseHeaders
(
String
...
headers
)
{
if
(
headers
==
null
)
{
return
new
HeadersRequestCondition
();
}
HeadersRequestCondition
headersCondition
=
new
HeadersRequestCondition
(
headers
);
// filter out Accept and Content-Type headers, they are dealt with by produces and consumes respectively
Set
<
HeadersRequestCondition
.
HeaderRequestCondition
>
filteredConditions
=
new
LinkedHashSet
<
HeadersRequestCondition
.
HeaderRequestCondition
>(
headersCondition
.
getConditions
());
for
(
Iterator
<
HeadersRequestCondition
.
HeaderRequestCondition
>
iterator
=
filteredConditions
.
iterator
();
iterator
.
hasNext
();)
{
HeadersRequestCondition
.
HeaderRequestCondition
headerCondition
=
iterator
.
next
();
if
(
ACCEPT_HEADER
.
equalsIgnoreCase
(
headerCondition
.
name
)
||
CONTENT_TYPE_HEADER
.
equalsIgnoreCase
(
headerCondition
.
name
))
{
iterator
.
remove
();
}
}
return
new
HeadersRequestCondition
(
filteredConditions
);
}
/**
* Parses the given consumes, and returns them as a single request condition.
*
* @param consumes the consumes
* @return the request condition
* @see org.springframework.web.bind.annotation.RequestMapping#consumes()
*/
public
static
ConsumesRequestCondition
parseConsumes
(
String
...
consumes
)
{
return
new
ConsumesRequestCondition
(
consumes
);
}
/**
* Parses the given consumes and {@code Content-Type} headers, and returns them as a single request condition. <p>Only
* {@code Content-Type} headers will be used, all other headers will be ignored.
*
* @param consumes the consumes
* @param headers the headers
* @return the request condition
* @see org.springframework.web.bind.annotation.RequestMapping#consumes()
*/
public
static
ConsumesRequestCondition
parseConsumes
(
String
[]
consumes
,
String
[]
headers
)
{
List
<
ConsumesRequestCondition
.
ConsumeRequestCondition
>
allConditions
=
parseContentTypeHeaders
(
headers
);
// ignore the default consumes() value if any content-type headers have been set
boolean
headersHasContentType
=
!
allConditions
.
isEmpty
();
boolean
consumesHasDefaultValue
=
consumes
.
length
==
1
&&
consumes
[
0
].
equals
(
"*/*"
);
if
(!
headersHasContentType
||
!
consumesHasDefaultValue
)
{
for
(
String
consume
:
consumes
)
{
allConditions
.
add
(
new
ConsumesRequestCondition
.
ConsumeRequestCondition
(
consume
));
}
}
return
new
ConsumesRequestCondition
(
allConditions
);
}
private
static
List
<
ConsumesRequestCondition
.
ConsumeRequestCondition
>
parseContentTypeHeaders
(
String
[]
headers
)
{
List
<
ConsumesRequestCondition
.
ConsumeRequestCondition
>
conditions
=
new
ArrayList
<
ConsumesRequestCondition
.
ConsumeRequestCondition
>();
HeadersRequestCondition
headersCondition
=
new
HeadersRequestCondition
(
headers
);
for
(
HeadersRequestCondition
.
HeaderRequestCondition
headerCondition
:
headersCondition
.
getConditions
())
{
if
(
CONTENT_TYPE_HEADER
.
equalsIgnoreCase
(
headerCondition
.
name
))
{
List
<
MediaType
>
mediaTypes
=
MediaType
.
parseMediaTypes
(
headerCondition
.
value
);
for
(
MediaType
mediaType
:
mediaTypes
)
{
conditions
.
add
(
new
ConsumesRequestCondition
.
ConsumeRequestCondition
(
mediaType
,
headerCondition
.
isNegated
));
}
}
}
return
conditions
;
}
/**
* Parses the given produces, and returns them as a single request condition.
*
* @param produces the produces
* @return the request condition
* @see org.springframework.web.bind.annotation.RequestMapping#produces()
*/
public
static
ProducesRequestCondition
parseProduces
(
String
...
produces
)
{
return
new
ProducesRequestCondition
(
produces
);
}
/**
* Parses the given produces and {@code Accept} headers, and returns them as a single request condition. <p>Only {@code
* Accept} headers will be used, all other headers will be ignored.
*
* @param produces the consumes
* @param headers the headers
* @return the request condition
* @see org.springframework.web.bind.annotation.RequestMapping#produces()
*/
public
static
ProducesRequestCondition
parseProduces
(
String
[]
produces
,
String
[]
headers
)
{
List
<
ProducesRequestCondition
.
ProduceRequestCondition
>
allConditions
=
parseAcceptHeaders
(
headers
);
// ignore the default consumes() value if any accept headers have been set
boolean
headersHasAccept
=
!
allConditions
.
isEmpty
();
boolean
producesHasDefaultValue
=
produces
.
length
==
1
&&
produces
[
0
].
equals
(
"*/*"
);
if
(!
headersHasAccept
||
!
producesHasDefaultValue
)
{
for
(
String
produce
:
produces
)
{
allConditions
.
add
(
new
ProducesRequestCondition
.
ProduceRequestCondition
(
produce
));
}
}
return
new
ProducesRequestCondition
(
allConditions
);
}
private
static
List
<
ProducesRequestCondition
.
ProduceRequestCondition
>
parseAcceptHeaders
(
String
[]
headers
)
{
List
<
ProducesRequestCondition
.
ProduceRequestCondition
>
allConditions
=
new
ArrayList
<
ProducesRequestCondition
.
ProduceRequestCondition
>();
HeadersRequestCondition
headersCondition
=
new
HeadersRequestCondition
(
headers
);
for
(
HeadersRequestCondition
.
HeaderRequestCondition
headerCondition
:
headersCondition
.
getConditions
())
{
if
(
ACCEPT_HEADER
.
equalsIgnoreCase
(
headerCondition
.
name
))
{
List
<
MediaType
>
mediaTypes
=
MediaType
.
parseMediaTypes
(
headerCondition
.
value
);
for
(
MediaType
mediaType
:
mediaTypes
)
{
allConditions
.
add
(
new
ProducesRequestCondition
.
ProduceRequestCondition
(
mediaType
,
headerCondition
.
isNegated
));
}
}
}
return
allConditions
;
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition
Composite
.java
→
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition
Support
.java
浏览文件 @
96b0752d
...
...
@@ -17,64 +17,62 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.Set
;
/**
*
Abstract base class for {@link RequestCondition} implementations that wrap other request conditions.
*
* @author
Arjen Poutsma
*
Base class for {@link RequestCondition}s.
*
* @author
Rossen Stoyanchev
* @since 3.1
*/
abstract
class
RequestConditionComposite
<
T
extends
RequestCondition
>
implements
RequestCondition
{
private
final
Set
<
T
>
conditions
;
protected
RequestConditionComposite
(
Collection
<
T
>
conditions
)
{
this
.
conditions
=
Collections
.
unmodifiableSet
(
new
LinkedHashSet
<
T
>(
conditions
));
}
protected
Set
<
T
>
getConditions
()
{
return
conditions
;
}
public
boolean
isEmpty
()
{
return
conditions
.
isEmpty
();
}
abstract
class
RequestConditionSupport
<
This
extends
RequestConditionSupport
<
This
>>
implements
RequestCondition
<
This
>
{
/**
* Returns the individual expressions a request condition is composed of such as
* URL patterns, HTTP request methods, parameter expressions, etc.
*/
protected
abstract
Collection
<?>
getContent
();
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
!=
null
&&
getClass
().
equals
(
o
.
getClass
()))
{
RequestCondition
Composite
other
=
(
RequestConditionComposite
)
o
;
return
this
.
conditions
.
equals
(
other
.
conditions
);
RequestCondition
Support
<?>
other
=
(
RequestConditionSupport
<?>
)
o
;
return
getContent
().
equals
(
other
.
getContent
()
);
}
return
false
;
}
@Override
public
int
hashCode
()
{
return
conditions
.
hashCode
();
return
getContent
()
.
hashCode
();
}
@Override
public
String
toString
()
{
StringBuilder
builder
=
new
StringBuilder
(
"["
);
String
infix
=
getToStringInfix
();
for
(
Iterator
<
T
>
iterator
=
conditions
.
iterator
();
iterator
.
hasNext
();)
{
RequestCondition
condition
=
iterator
.
next
();
builder
.
append
(
condition
.
toString
());
for
(
Iterator
<?>
iterator
=
getContent
().
iterator
();
iterator
.
hasNext
();)
{
Object
expression
=
iterator
.
next
();
builder
.
append
(
expression
.
toString
());
if
(
iterator
.
hasNext
())
{
builder
.
append
(
infix
);
if
(
isLogicalConjunction
())
{
builder
.
append
(
" && "
);
}
else
{
builder
.
append
(
" || "
);
}
}
}
builder
.
append
(
"]"
);
return
builder
.
toString
();
}
protected
abstract
String
getToStringInfix
();
/**
* Returns {@code true} if the individual expressions of the condition are combined via logical
* conjunction (" && "); or {@code false} otherwise.
*/
protected
abstract
boolean
isLogicalConjunction
();
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestCondition.java
浏览文件 @
96b0752d
...
...
@@ -22,132 +22,102 @@ import java.util.Collections;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.web.bind.annotation.RequestMethod
;
/**
* Represents a collection of {@link RequestMethod} conditions, typically obtained from {@link
* org.springframework.web.bind.annotation.RequestMapping#method() @RequestMapping.methods()}.
*
* A logical disjunction (' || ') request condition that matches a request against a set of {@link RequestMethod}s.
*
* <p>If the condition is created with 0 HTTP request methods, it matches to every request.
*
* @author Arjen Poutsma
* @
see RequestConditionFactory#parseMethods(RequestMethod...)
* @
author Rossen Stoyanchev
* @since 3.1
*/
public
class
RequestMethodsRequestCondition
extends
LogicalDisjunctionRequestCondition
<
RequestMethodsRequestCondition
.
RequestMethodRequestCondition
>
implements
Comparable
<
RequestMethodsRequestCondition
>
{
public
class
RequestMethodsRequestCondition
extends
RequestConditionSupport
<
RequestMethodsRequestCondition
>
{
private
RequestMethodsRequestCondition
(
Collection
<
RequestMethodRequestCondition
>
conditions
)
{
super
(
conditions
);
}
private
final
Set
<
RequestMethod
>
methods
;
RequestMethodsRequestCondition
(
RequestMethod
...
methods
)
{
this
(
parseConditions
(
Arrays
.
asList
(
methods
)));
/**
* Create a {@link RequestMethodsRequestCondition} with the given {@link RequestMethod}s.
* @param requestMethods 0 or more HTTP request methods; if 0 the condition will match to every request.
*/
public
RequestMethodsRequestCondition
(
RequestMethod
...
requestMethods
)
{
this
(
asList
(
requestMethods
));
}
private
static
Set
<
RequestMethodRequestCondition
>
parseConditions
(
List
<
RequestMethod
>
methods
)
{
Set
<
RequestMethodRequestCondition
>
conditions
=
new
LinkedHashSet
<
RequestMethodRequestCondition
>(
methods
.
size
());
for
(
RequestMethod
method
:
methods
)
{
conditions
.
add
(
new
RequestMethodRequestCondition
(
method
));
}
return
conditions
;
private
static
List
<
RequestMethod
>
asList
(
RequestMethod
...
requestMethods
)
{
return
requestMethods
!=
null
?
Arrays
.
asList
(
requestMethods
)
:
Collections
.<
RequestMethod
>
emptyList
();
}
/**
*
Creates an empty set of method request conditions
.
*
Private constructor
.
*/
p
ublic
RequestMethodsRequestCondition
(
)
{
this
(
Collections
.<
RequestMethodRequestCondition
>
emptySet
(
));
}
p
rivate
RequestMethodsRequestCondition
(
Collection
<
RequestMethod
>
requestMethods
)
{
this
.
methods
=
Collections
.
unmodifiableSet
(
new
LinkedHashSet
<
RequestMethod
>(
requestMethods
));
}
/**
* Returns all {@link RequestMethod}s contained in this condition.
*/
public
Set
<
RequestMethod
>
getMethods
()
{
Set
<
RequestMethod
>
result
=
new
LinkedHashSet
<
RequestMethod
>();
for
(
RequestMethodRequestCondition
condition
:
getConditions
())
{
result
.
add
(
condition
.
getMethod
());
}
return
result
;
return
methods
;
}
public
int
compareTo
(
RequestMethodsRequestCondition
other
)
{
return
other
.
getConditions
().
size
()
-
this
.
getConditions
().
size
();
@Override
protected
Collection
<
RequestMethod
>
getContent
()
{
return
methods
;
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
false
;
}
/**
* Returns a new {@code RequestMethodsRequestCondition} that contains all conditions that match the request.
*
* @param request the request
* @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match
* Returns a new instance with a union of the HTTP request methods from "this" and the "other" instance.
*/
public
RequestMethodsRequestCondition
combine
(
RequestMethodsRequestCondition
other
)
{
Set
<
RequestMethod
>
set
=
new
LinkedHashSet
<
RequestMethod
>(
this
.
methods
);
set
.
addAll
(
other
.
methods
);
return
new
RequestMethodsRequestCondition
(
set
);
}
/**
* Checks if any of the HTTP request methods match the given request and returns an instance that
* contain the matching request method.
* @param request the current request
* @return the same instance if the condition contains no request method;
* or a new condition with the matching request method; or {@code null} if no request methods match.
*/
public
RequestMethodsRequestCondition
getMatchingCondition
(
HttpServletRequest
request
)
{
if
(
isEmpty
())
{
if
(
methods
.
isEmpty
())
{
return
this
;
}
else
{
if
(
match
(
request
))
{
return
new
RequestMethodsRequestCondition
(
RequestMethod
.
valueOf
(
request
.
getMethod
()));
}
else
{
return
null
;
RequestMethod
incomingRequestMethod
=
RequestMethod
.
valueOf
(
request
.
getMethod
());
for
(
RequestMethod
method
:
methods
)
{
if
(
method
.
equals
(
incomingRequestMethod
))
{
return
new
RequestMethodsRequestCondition
(
method
);
}
}
return
null
;
}
/**
* Combines this collection of request method conditions with another by combining all methods into a logical OR.
*
* @param other the condition to combine with
* Returns:
* <ul>
* <li>0 if the two conditions contain the same number of HTTP request methods.
* <li>Less than 1 if "this" instance has an HTTP request method but "other" doesn't.
* <li>Greater than 1 "other" has an HTTP request method but "this" doesn't.
* </ul>
*
* <p>It is assumed that both instances have been obtained via {@link #getMatchingCondition(HttpServletRequest)}
* and therefore each instance contains the matching HTTP request method only or is otherwise empty.
*/
public
RequestMethodsRequestCondition
combine
(
RequestMethodsRequestCondition
other
)
{
Set
<
RequestMethodRequestCondition
>
conditions
=
new
LinkedHashSet
<
RequestMethodRequestCondition
>(
getConditions
());
conditions
.
addAll
(
other
.
getConditions
());
return
new
RequestMethodsRequestCondition
(
conditions
);
public
int
compareTo
(
RequestMethodsRequestCondition
other
,
HttpServletRequest
request
)
{
return
other
.
methods
.
size
()
-
this
.
methods
.
size
();
}
static
class
RequestMethodRequestCondition
implements
RequestCondition
{
private
final
RequestMethod
method
;
RequestMethodRequestCondition
(
RequestMethod
method
)
{
this
.
method
=
method
;
}
RequestMethod
getMethod
()
{
return
method
;
}
public
boolean
match
(
HttpServletRequest
request
)
{
RequestMethod
method
=
RequestMethod
.
valueOf
(
request
.
getMethod
());
return
this
.
method
.
equals
(
method
);
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
!=
null
&&
obj
instanceof
RequestMethodRequestCondition
)
{
RequestMethodRequestCondition
other
=
(
RequestMethodRequestCondition
)
obj
;
return
this
.
method
.
equals
(
other
.
method
);
}
return
false
;
}
@Override
public
int
hashCode
()
{
return
method
.
hashCode
();
}
@Override
public
String
toString
()
{
return
method
.
toString
();
}
}
}
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoComparatorTests.java
浏览文件 @
96b0752d
...
...
@@ -16,6 +16,11 @@
package
org.springframework.web.servlet.mvc.method
;
import
static
java
.
util
.
Arrays
.
asList
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertSame
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.lang.reflect.Method
;
import
java.util.Collections
;
import
java.util.Comparator
;
...
...
@@ -23,17 +28,14 @@ import java.util.List;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
;
import
org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory
;
import
org.springframework.web.servlet.mvc.method.condition.ParamsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ProducesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.RequestMethodsRequestCondition
;
import
org.springframework.web.util.UrlPathHelper
;
import
static
java
.
util
.
Arrays
.*;
import
static
org
.
junit
.
Assert
.*;
/**
* Test fixture with {@link RequestMappingHandlerMapping} testing its {@link RequestMappingInfo} comparator.
*
...
...
@@ -57,8 +59,8 @@ public class RequestMappingInfoComparatorTests {
request
.
setRequestURI
(
"/foo"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
lookupPath
,
request
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
asList
(
"/fo*"
),
null
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
asList
(
"/foo"
),
null
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
new
String
[]{
"/fo*"
}
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
new
String
[]{
"/foo"
}
);
assertEquals
(
1
,
comparator
.
compare
(
key1
,
key2
));
}
...
...
@@ -68,8 +70,8 @@ public class RequestMappingInfoComparatorTests {
request
.
setRequestURI
(
"/foo"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
lookupPath
,
request
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
asList
(
"/foo*"
),
null
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
asList
(
"/foo*"
),
null
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
new
String
[]{
"/foo*"
}
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
new
String
[]{
"/foo*"
}
);
assertEquals
(
0
,
comparator
.
compare
(
key1
,
key2
));
}
...
...
@@ -78,20 +80,20 @@ public class RequestMappingInfoComparatorTests {
public
void
greaterNumberOfMatchingPatternsWins
()
throws
Exception
{
request
.
setRequestURI
(
"/foo.html"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
asList
(
"/foo"
,
"*.jpeg"
),
null
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
asList
(
"/foo"
,
"*.html"
),
null
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
new
String
[]{
"/foo"
,
"*.jpeg"
}
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
new
String
[]{
"/foo"
,
"*.html"
}
);
RequestMappingInfo
match1
=
handlerMapping
.
getMatchingMapping
(
key1
,
lookupPath
,
request
);
RequestMappingInfo
match2
=
handlerMapping
.
getMatchingMapping
(
key2
,
lookupPath
,
request
);
List
<
RequestMappingInfo
>
matches
=
asList
(
match1
,
match2
);
Collections
.
sort
(
matches
,
handlerMapping
.
getMappingComparator
(
lookupPath
,
request
));
assertSame
(
match2
.
getPatterns
(),
matches
.
get
(
0
).
getPatterns
());
assertSame
(
match2
.
getPatterns
Condition
(),
matches
.
get
(
0
).
getPatternsCondition
());
}
@Test
public
void
oneMethodWinsOverNone
()
{
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
""
,
request
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
null
,
null
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
null
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
null
,
new
RequestMethod
[]
{
RequestMethod
.
GET
});
assertEquals
(
1
,
comparator
.
compare
(
key1
,
key2
));
...
...
@@ -99,10 +101,11 @@ public class RequestMappingInfoComparatorTests {
@Test
public
void
methodsAndParams
()
{
RequestMappingInfo
empty
=
new
RequestMappingInfo
(
null
,
null
);
RequestMappingInfo
empty
=
new
RequestMappingInfo
(
null
);
RequestMappingInfo
oneMethod
=
new
RequestMappingInfo
(
null
,
new
RequestMethod
[]
{
RequestMethod
.
GET
});
RequestMappingInfo
oneMethodOneParam
=
new
RequestMappingInfo
(
null
,
RequestConditionFactory
.
parseMethods
(
RequestMethod
.
GET
),
RequestConditionFactory
.
parseParams
(
"foo"
),
null
,
null
,
null
);
new
RequestMappingInfo
(
null
,
new
RequestMethodsRequestCondition
(
RequestMethod
.
GET
),
new
ParamsRequestCondition
(
"foo"
),
null
,
null
,
null
);
List
<
RequestMappingInfo
>
list
=
asList
(
empty
,
oneMethod
,
oneMethodOneParam
);
Collections
.
shuffle
(
list
);
Collections
.
sort
(
list
,
handlerMapping
.
getMappingComparator
(
""
,
request
));
...
...
@@ -114,9 +117,9 @@ public class RequestMappingInfoComparatorTests {
@Test
public
void
produces
()
{
RequestMappingInfo
html
=
new
RequestMappingInfo
(
null
,
null
,
null
,
null
,
null
,
RequestConditionFactory
.
parseProduces
(
"text/html"
));
RequestMappingInfo
xml
=
new
RequestMappingInfo
(
null
,
null
,
null
,
null
,
null
,
RequestConditionFactory
.
parseProduces
(
"application/xml"
));
RequestMappingInfo
none
=
new
RequestMappingInfo
(
null
,
null
);
RequestMappingInfo
html
=
new
RequestMappingInfo
(
null
,
null
,
null
,
null
,
null
,
new
ProducesRequestCondition
(
"text/html"
));
RequestMappingInfo
xml
=
new
RequestMappingInfo
(
null
,
null
,
null
,
null
,
null
,
new
ProducesRequestCondition
(
"application/xml"
));
RequestMappingInfo
none
=
new
RequestMappingInfo
(
null
);
request
.
addHeader
(
"Accept"
,
"application/xml, text/html"
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
""
,
request
);
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java
浏览文件 @
96b0752d
...
...
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertSame;
import
static
org
.
junit
.
Assert
.
fail
;
import
java.lang.reflect.Method
;
import
java.util.Arrays
;
import
java.util.Map
;
import
org.junit.Before
;
...
...
@@ -42,9 +41,13 @@ import org.springframework.web.servlet.HandlerInterceptor;
import
org.springframework.web.servlet.HandlerMapping
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
import
org.springframework.web.servlet.handler.MappedInterceptor
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
;
import
org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory
;
import
org.springframework.web.servlet.mvc.method.condition.ConsumesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ParamsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.PatternsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ProducesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.RequestMethodsRequestCondition
;
import
org.springframework.web.util.UrlPathHelper
;
/**
...
...
@@ -129,7 +132,7 @@ public class RequestMappingInfoHandlerMappingTests {
@Test
public
void
uriTemplateVariables
()
{
RequestMappingInfo
key
=
new
RequestMappingInfo
(
Arrays
.
asList
(
"/{path1}/{path2}"
),
null
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
new
String
[]
{
"/{path1}/{path2}"
}
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/1/2"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
...
...
@@ -197,12 +200,13 @@ public class RequestMappingInfoHandlerMappingTests {
@Override
protected
RequestMappingInfo
getMappingForMethod
(
Method
method
,
Class
<?>
handlerType
)
{
RequestMapping
annotation
=
AnnotationUtils
.
findAnnotation
(
method
,
RequestMapping
.
class
);
return
new
RequestMappingInfo
(
Arrays
.
asList
(
annotation
.
value
()),
RequestConditionFactory
.
parseMethods
(
annotation
.
method
()),
RequestConditionFactory
.
parseParams
(
annotation
.
params
()),
RequestConditionFactory
.
parseHeaders
(
annotation
.
headers
()),
RequestConditionFactory
.
parseConsumes
(
annotation
.
consumes
(),
annotation
.
headers
()),
RequestConditionFactory
.
parseProduces
(
annotation
.
produces
(),
annotation
.
headers
()));
return
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
annotation
.
value
(),
getUrlPathHelper
(),
getPathMatcher
()),
new
RequestMethodsRequestCondition
(
annotation
.
method
()),
new
ParamsRequestCondition
(
annotation
.
params
()),
new
HeadersRequestCondition
(
annotation
.
headers
()),
new
ConsumesRequestCondition
(
annotation
.
consumes
(),
annotation
.
headers
()),
new
ProducesRequestCondition
(
annotation
.
produces
(),
annotation
.
headers
()));
}
}
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java
浏览文件 @
96b0752d
...
...
@@ -16,20 +16,19 @@
package
org.springframework.web.servlet.mvc.method
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
springframework
.
web
.
bind
.
annotation
.
RequestMethod
.
GET
;
import
static
org
.
springframework
.
web
.
bind
.
annotation
.
RequestMethod
.
POST
;
import
org.junit.Test
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.util.AntPathMatcher
;
import
org.springframework.util.PathMatcher
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory
;
import
org.springframework.web.util.UrlPathHelper
;
import
static
java
.
util
.
Arrays
.*;
import
static
java
.
util
.
Collections
.*;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
springframework
.
web
.
bind
.
annotation
.
RequestMethod
.*;
import
org.springframework.web.servlet.mvc.method.condition.ConsumesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ParamsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.PatternsRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.ProducesRequestCondition
;
/**
* Test fixture for {@link RequestMappingInfo} tests.
...
...
@@ -41,8 +40,8 @@ public class RequestMappingInfoTests {
@Test
public
void
equals
()
{
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
methods
(
GET
)
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
methods
(
GET
)
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
new
String
[]
{
"/foo"
},
GET
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
new
String
[]
{
"/foo"
},
GET
);
assertEquals
(
key1
,
key2
);
assertEquals
(
key1
.
hashCode
(),
key2
.
hashCode
());
...
...
@@ -50,8 +49,8 @@ public class RequestMappingInfoTests {
@Test
public
void
equalsPrependSlash
()
{
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
methods
(
GET
)
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
singleton
(
"foo"
),
methods
(
GET
)
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
new
String
[]
{
"/foo"
},
GET
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
new
String
[]
{
"foo"
},
GET
);
assertEquals
(
key1
,
key2
);
assertEquals
(
key1
.
hashCode
(),
key2
.
hashCode
());
...
...
@@ -59,213 +58,190 @@ public class RequestMappingInfoTests {
@Test
public
void
combinePatterns
()
{
AntPathMatcher
pathMatcher
=
new
AntPathMatcher
();
RequestMappingInfo
key1
=
createKeyFromPatterns
(
"/t1"
,
"/t2"
);
RequestMappingInfo
key2
=
createKeyFromPatterns
(
"/m1"
,
"/m2"
);
RequestMappingInfo
key3
=
createKeyFromPatterns
(
"/t1/m1"
,
"/t1/m2"
,
"/t2/m1"
,
"/t2/m2"
);
assertEquals
(
key3
.
getPatterns
(),
key1
.
combine
(
key2
,
pathMatcher
).
getPatterns
());
key1
=
createKeyFromPatterns
(
"/t1"
);
key2
=
createKeyFromPatterns
();
key3
=
createKeyFromPatterns
(
"/t1"
);
assertEquals
(
key3
.
getPatterns
(),
key1
.
combine
(
key2
,
pathMatcher
).
getPatterns
());
key1
=
createKeyFromPatterns
();
key2
=
createKeyFromPatterns
(
"/m1"
);
key3
=
createKeyFromPatterns
(
"/m1"
);
assertEquals
(
key3
.
getPatterns
(),
key1
.
combine
(
key2
,
pathMatcher
).
getPatterns
());
key1
=
createKeyFromPatterns
();
key2
=
createKeyFromPatterns
();
key3
=
createKeyFromPatterns
(
""
);
assertEquals
(
key3
.
getPatterns
(),
key1
.
combine
(
key2
,
pathMatcher
).
getPatterns
());
key1
=
createKeyFromPatterns
(
"/t1"
);
key2
=
createKeyFromPatterns
(
""
);
key3
=
createKeyFromPatterns
(
"/t1"
);
assertEquals
(
key3
.
getPatterns
(),
key1
.
combine
(
key2
,
pathMatcher
).
getPatterns
());
RequestMappingInfo
key1
=
createFromPatterns
(
"/t1"
,
"/t2"
);
RequestMappingInfo
key2
=
createFromPatterns
(
"/m1"
,
"/m2"
);
RequestMappingInfo
key3
=
createFromPatterns
(
"/t1/m1"
,
"/t1/m2"
,
"/t2/m1"
,
"/t2/m2"
);
assertEquals
(
key3
.
getPatternsCondition
(),
key1
.
combine
(
key2
).
getPatternsCondition
());
key1
=
createFromPatterns
(
"/t1"
);
key2
=
createFromPatterns
();
key3
=
createFromPatterns
(
"/t1"
);
assertEquals
(
key3
.
getPatternsCondition
(),
key1
.
combine
(
key2
).
getPatternsCondition
());
key1
=
createFromPatterns
();
key2
=
createFromPatterns
(
"/m1"
);
key3
=
createFromPatterns
(
"/m1"
);
assertEquals
(
key3
.
getPatternsCondition
(),
key1
.
combine
(
key2
).
getPatternsCondition
());
key1
=
createFromPatterns
();
key2
=
createFromPatterns
();
key3
=
createFromPatterns
(
""
);
assertEquals
(
key3
.
getPatternsCondition
(),
key1
.
combine
(
key2
).
getPatternsCondition
());
key1
=
createFromPatterns
(
"/t1"
);
key2
=
createFromPatterns
(
""
);
key3
=
createFromPatterns
(
"/t1"
);
assertEquals
(
key3
.
getPatternsCondition
(),
key1
.
combine
(
key2
).
getPatternsCondition
());
}
@Test
public
void
matchPatternsToRequest
()
{
UrlPathHelper
pathHelper
=
new
UrlPathHelper
();
PathMatcher
pathMatcher
=
new
AntPathMatcher
();
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
pathHelper
.
getLookupPathForRequest
(
request
),
request
,
pathMatcher
);
RequestMappingInfo
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
(
request
);
assertNotNull
(
match
);
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo/bar"
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo/*"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
pathHelper
.
getLookupPathForRequest
(
request
),
request
,
pathMatcher
);
match
=
createFromPatterns
(
"/foo/*"
).
getMatchingRequestMapping
(
request
);
assertNotNull
(
"Pattern match"
,
match
);
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo.html"
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
pathHelper
.
getLookupPathForRequest
(
request
),
request
,
pathMatcher
);
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
(
request
);
assertNotNull
(
"Implicit match by extension"
,
match
);
assertEquals
(
"Contains matched pattern"
,
"/foo.*"
,
match
.
getPatterns
().
iterator
().
next
());
assertEquals
(
"Contains matched pattern"
,
"/foo.*"
,
match
.
getPatterns
Condition
().
getPatterns
().
iterator
().
next
());
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo/"
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
pathHelper
.
getLookupPathForRequest
(
request
),
request
,
pathMatcher
);
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
(
request
);
assertNotNull
(
"Implicit match by trailing slash"
,
match
);
assertEquals
(
"Contains matched pattern"
,
"/foo/"
,
match
.
getPatterns
().
iterator
().
next
());
assertEquals
(
"Contains matched pattern"
,
"/foo/"
,
match
.
getPatterns
Condition
().
getPatterns
().
iterator
().
next
());
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo.html"
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo.jpg"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
pathHelper
.
getLookupPathForRequest
(
request
),
request
,
pathMatcher
);
match
=
createFromPatterns
(
"/foo.jpg"
).
getMatchingRequestMapping
(
request
);
assertNull
(
"Implicit match ignored if pattern has extension"
,
match
);
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo.html"
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo.jpg"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
pathHelper
.
getLookupPathForRequest
(
request
),
request
,
pathMatcher
);
match
=
createFromPatterns
(
"/foo.jpg"
).
getMatchingRequestMapping
(
request
);
assertNull
(
"Implicit match ignored on pattern with trailing slash"
,
match
);
}
@Test
public
void
matchRequestMethods
()
{
PathMatcher
pathMatcher
=
new
AntPathMatcher
();
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
RequestMappingInfo
key
=
createFromPatterns
(
"/foo"
);
RequestMappingInfo
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
(
request
);
assertNotNull
(
"No method matches any method"
,
match
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
methods
(
GET
)
);
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
key
=
new
RequestMappingInfo
(
new
String
[]{
"/foo"
},
GET
);
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNotNull
(
"Exact match"
,
match
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
methods
(
POST
)
);
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
key
=
new
RequestMappingInfo
(
new
String
[]{
"/foo"
},
POST
);
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNull
(
"No match"
,
match
);
}
@Test
public
void
matchingKeyContent
()
{
PathMatcher
pathMatcher
=
new
AntPathMatcher
();
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
asList
(
"/foo*"
,
"/bar"
),
methods
(
GET
,
POST
)
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
RequestMappingInfo
expected
=
new
RequestMappingInfo
(
singleton
(
"/foo*"
),
methods
(
GET
)
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
new
String
[]
{
"/foo*"
,
"/bar"
},
GET
,
POST
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
RequestMappingInfo
expected
=
new
RequestMappingInfo
(
new
String
[]
{
"/foo*"
},
GET
);
assertEquals
(
"Matching RequestKey contains matched patterns and methods only"
,
expected
,
match
);
key
=
new
RequestMappingInfo
(
asList
(
"/**"
,
"/foo*"
,
"/foo"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
expected
=
new
RequestMappingInfo
(
asList
(
"/foo"
,
"/foo*"
,
"/**"
),
null
);
key
=
createFromPatterns
(
"/**"
,
"/foo*"
,
"/foo"
);
match
=
key
.
getMatchingRequestMapping
(
request
);
expected
=
createFromPatterns
(
"/foo"
,
"/foo*"
,
"/**"
);
assertEquals
(
"Matched patterns are sorted with best match at the top"
,
expected
,
match
);
}
@Test
public
void
paramsCondition
()
{
PathMatcher
pathMatcher
=
new
AntPathMatcher
();
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
request
.
setParameter
(
"foo"
,
"bar"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
asList
(
"/foo"
),
null
,
RequestConditionFactory
.
parseParams
(
"foo=bar"
),
null
,
null
,
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
new
ParamsRequestCondition
(
"foo=bar"
),
null
,
null
,
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNotNull
(
match
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
,
RequestConditionFactory
.
parseParams
(
"foo!=bar"
),
null
,
null
,
null
);
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
new
ParamsRequestCondition
(
"foo!=bar"
),
null
,
null
,
null
);
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNull
(
match
);
}
@Test
public
void
headersCondition
()
{
PathMatcher
pathMatcher
=
new
AntPathMatcher
();
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
request
.
addHeader
(
"foo"
,
"bar"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
,
null
,
RequestConditionFactory
.
parseHeaders
(
"foo=bar"
),
null
,
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
new
HeadersRequestCondition
(
"foo=bar"
),
null
,
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNotNull
(
match
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
,
null
,
RequestConditionFactory
.
parseHeaders
(
"foo!=bar"
),
null
,
null
);
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
new
HeadersRequestCondition
(
"foo!=bar"
),
null
,
null
);
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNull
(
match
);
}
@Test
public
void
consumesCondition
()
{
PathMatcher
pathMatcher
=
new
AntPathMatcher
();
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
request
.
setContentType
(
"text/plain"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
,
null
,
null
,
RequestConditionFactory
.
parseConsumes
(
"text/plain"
),
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
null
,
new
ConsumesRequestCondition
(
"text/plain"
),
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNotNull
(
match
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
,
null
,
null
,
RequestConditionFactory
.
parseConsumes
(
"application/xml"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
null
,
new
ConsumesRequestCondition
(
"application/xml"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNull
(
match
);
}
@Test
public
void
producesCondition
()
{
PathMatcher
pathMatcher
=
new
AntPathMatcher
();
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
request
.
addHeader
(
"Accept"
,
"text/plain"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
,
null
,
null
,
null
,
RequestConditionFactory
.
parseProduces
(
"text/plain"
));
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
null
,
null
,
new
ProducesRequestCondition
(
"text/plain"
));
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNotNull
(
match
);
key
=
new
RequestMappingInfo
(
singleton
(
"/foo"
),
null
,
null
,
null
,
null
,
RequestConditionFactory
.
parseProduces
(
"application/xml"
));
match
=
key
.
getMatchingRequestMapping
(
lookupPath
,
request
,
pathMatcher
);
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
null
,
null
,
new
ProducesRequestCondition
(
"application/xml"
));
match
=
key
.
getMatchingRequestMapping
(
request
);
assertNull
(
match
);
}
private
RequestMappingInfo
createKeyFromPatterns
(
String
...
patterns
)
{
return
new
RequestMappingInfo
(
asList
(
patterns
),
null
);
}
private
RequestMethod
[]
methods
(
RequestMethod
...
methods
)
{
if
(
methods
!=
null
)
{
return
methods
;
}
else
{
return
new
RequestMethod
[
0
];
}
private
RequestMappingInfo
createFromPatterns
(
String
...
patterns
)
{
return
new
RequestMappingInfo
(
patterns
);
}
}
\ No newline at end of file
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/ConsumesRequestConditionTests.java
浏览文件 @
96b0752d
...
...
@@ -16,13 +16,17 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Set
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
org.junit.Test
;
import
java.util.Collection
;
import
org.junit.Test
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
static
org
.
junit
.
Assert
.*;
import
org.springframework.web.servlet.mvc.method.condition.ConsumesRequestCondition.ConsumeMediaTypeExpression
;
/**
* @author Arjen Poutsma
...
...
@@ -31,75 +35,79 @@ public class ConsumesRequestConditionTests {
@Test
public
void
consumesMatch
()
{
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"text/plain"
);
Consumes
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"text/plain"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
setContentType
(
"text/plain"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
negatedConsumesMatch
()
{
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"!text/plain"
);
Consumes
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"!text/plain"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
setContentType
(
"text/plain"
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
consumesWildcardMatch
()
{
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"text/*"
);
Consumes
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"text/*"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
setContentType
(
"text/plain"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
consumesMultipleMatch
()
{
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"text/plain"
,
"application/xml"
);
Consumes
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"text/plain"
,
"application/xml"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
setContentType
(
"text/plain"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
consumesSingleNoMatch
()
{
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"text/plain"
);
Consumes
RequestCondition
condition
=
new
ConsumesRequestCondition
(
"text/plain"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
setContentType
(
"application/xml"
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
compareToSingle
()
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
ConsumesRequestCondition
condition1
=
new
ConsumesRequestCondition
(
"text/plain"
);
ConsumesRequestCondition
condition2
=
new
ConsumesRequestCondition
(
"text/*"
);
int
result
=
condition1
.
compareTo
(
condition2
);
int
result
=
condition1
.
compareTo
(
condition2
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition2
.
compareTo
(
condition1
);
result
=
condition2
.
compareTo
(
condition1
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
}
@Test
public
void
compareToMultiple
()
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
ConsumesRequestCondition
condition1
=
new
ConsumesRequestCondition
(
"*/*"
,
"text/plain"
);
ConsumesRequestCondition
condition2
=
new
ConsumesRequestCondition
(
"text/*"
,
"text/plain;q=0.7"
);
int
result
=
condition1
.
compareTo
(
condition2
);
int
result
=
condition1
.
compareTo
(
condition2
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition2
.
compareTo
(
condition1
);
result
=
condition2
.
compareTo
(
condition1
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
}
...
...
@@ -126,28 +134,11 @@ public class ConsumesRequestConditionTests {
public
void
parseConsumesAndHeaders
()
{
String
[]
consumes
=
new
String
[]
{
"text/plain"
};
String
[]
headers
=
new
String
[]{
"foo=bar"
,
"content-type=application/xml,application/pdf"
};
ConsumesRequestCondition
condition
=
RequestConditionFactory
.
parseConsumes
(
consumes
,
headers
);
ConsumesRequestCondition
condition
=
new
ConsumesRequestCondition
(
consumes
,
headers
);
assertConditions
(
condition
,
"text/plain"
,
"application/xml"
,
"application/pdf"
);
}
@Test
public
void
parseConsumesDefault
()
{
String
[]
consumes
=
new
String
[]
{
"*/*"
};
String
[]
headers
=
new
String
[
0
];
ConsumesRequestCondition
condition
=
RequestConditionFactory
.
parseConsumes
(
consumes
,
headers
);
assertConditions
(
condition
,
"*/*"
);
}
@Test
public
void
parseConsumesDefaultAndHeaders
()
{
String
[]
consumes
=
new
String
[]
{
"*/*"
};
String
[]
headers
=
new
String
[]{
"foo=bar"
,
"content-type=text/plain"
};
ConsumesRequestCondition
condition
=
RequestConditionFactory
.
parseConsumes
(
consumes
,
headers
);
assertConditions
(
condition
,
"text/plain"
);
}
@Test
public
void
getMatchingCondition
()
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
...
...
@@ -165,12 +156,12 @@ public class ConsumesRequestConditionTests {
}
private
void
assertConditions
(
ConsumesRequestCondition
condition
,
String
...
expected
)
{
Set
<
ConsumesRequestCondition
.
ConsumeRequestCondition
>
conditions
=
condition
.
getConditions
();
assertEquals
(
"Invalid amount of conditions"
,
condit
ions
.
size
(),
expected
.
length
);
Collection
<
ConsumeMediaTypeExpression
>
expressions
=
condition
.
getContent
();
assertEquals
(
"Invalid amount of conditions"
,
express
ions
.
size
(),
expected
.
length
);
for
(
String
s
:
expected
)
{
boolean
found
=
false
;
for
(
Consume
sRequestCondition
.
ConsumeRequestCondition
requestCondition
:
condit
ions
)
{
String
conditionMediaType
=
requestCondition
.
getMediaType
().
toString
();
for
(
Consume
MediaTypeExpression
expr
:
express
ions
)
{
String
conditionMediaType
=
expr
.
getMediaType
().
toString
();
if
(
conditionMediaType
.
equals
(
s
))
{
found
=
true
;
break
;
...
...
@@ -181,12 +172,6 @@ public class ConsumesRequestConditionTests {
fail
(
"Condition ["
+
s
+
"] not found"
);
}
}
}
}
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestConditionTests.java
浏览文件 @
96b0752d
...
...
@@ -16,13 +16,17 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Set
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
org.junit.Test
;
import
java.util.Collection
;
import
org.junit.Test
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
static
org
.
junit
.
Assert
.*;
import
org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondition.HeaderExpression
;
/**
* @author Arjen Poutsma
...
...
@@ -40,81 +44,83 @@ public class HeadersRequestConditionTests {
@Test
public
void
headerPresent
()
{
RequestCondition
condition
=
new
HeadersRequestCondition
(
"accept"
);
Headers
RequestCondition
condition
=
new
HeadersRequestCondition
(
"accept"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
""
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
headerPresentNoMatch
()
{
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo"
);
Headers
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"bar"
,
""
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
headerNotPresent
()
{
RequestCondition
condition
=
new
HeadersRequestCondition
(
"!accept"
);
Headers
RequestCondition
condition
=
new
HeadersRequestCondition
(
"!accept"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
headerValueMatch
()
{
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo=bar"
);
Headers
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo=bar"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"foo"
,
"bar"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
headerValueNoMatch
()
{
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo=bar"
);
Headers
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo=bar"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"foo"
,
"bazz"
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
headerCaseSensitiveValueMatch
()
{
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo=Bar"
);
Headers
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo=Bar"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"foo"
,
"bar"
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
headerValueMatchNegated
()
{
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo!=bar"
);
Headers
RequestCondition
condition
=
new
HeadersRequestCondition
(
"foo!=bar"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"foo"
,
"baz"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
compareTo
()
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
HeadersRequestCondition
condition1
=
new
HeadersRequestCondition
(
"foo"
,
"bar"
,
"baz"
);
HeadersRequestCondition
condition2
=
new
HeadersRequestCondition
(
"foo"
,
"bar"
);
int
result
=
condition1
.
compareTo
(
condition2
);
int
result
=
condition1
.
compareTo
(
condition2
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition2
.
compareTo
(
condition1
);
result
=
condition2
.
compareTo
(
condition1
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
}
...
...
@@ -125,7 +131,7 @@ public class HeadersRequestConditionTests {
HeadersRequestCondition
condition2
=
new
HeadersRequestCondition
(
"foo=baz"
);
HeadersRequestCondition
result
=
condition1
.
combine
(
condition2
);
Set
<
HeadersRequestCondition
.
HeaderRequestCondition
>
conditions
=
result
.
getConditions
();
Collection
<
HeaderExpression
>
conditions
=
result
.
getContent
();
assertEquals
(
2
,
conditions
.
size
());
}
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestConditionTests.java
浏览文件 @
96b0752d
...
...
@@ -16,13 +16,17 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Set
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
org.junit.Test
;
import
java.util.Collection
;
import
org.junit.Test
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
static
org
.
junit
.
Assert
.*;
import
org.springframework.web.servlet.mvc.method.condition.ParamsRequestCondition.ParamExpression
;
/**
* @author Arjen Poutsma
...
...
@@ -41,62 +45,64 @@ public class ParamsRequestConditionTests {
@Test
public
void
paramPresent
()
{
RequestCondition
condition
=
new
ParamsRequestCondition
(
"foo"
);
Params
RequestCondition
condition
=
new
ParamsRequestCondition
(
"foo"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addParameter
(
"foo"
,
""
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
paramPresentNoMatch
()
{
RequestCondition
condition
=
new
ParamsRequestCondition
(
"foo"
);
Params
RequestCondition
condition
=
new
ParamsRequestCondition
(
"foo"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"bar"
,
""
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
paramNotPresent
()
{
RequestCondition
condition
=
new
ParamsRequestCondition
(
"!foo"
);
Params
RequestCondition
condition
=
new
ParamsRequestCondition
(
"!foo"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
paramValueMatch
()
{
RequestCondition
condition
=
new
ParamsRequestCondition
(
"foo=bar"
);
Params
RequestCondition
condition
=
new
ParamsRequestCondition
(
"foo=bar"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addParameter
(
"foo"
,
"bar"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
paramValueNoMatch
()
{
RequestCondition
condition
=
new
ParamsRequestCondition
(
"foo=bar"
);
Params
RequestCondition
condition
=
new
ParamsRequestCondition
(
"foo=bar"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addParameter
(
"foo"
,
"bazz"
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
compareTo
()
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
ParamsRequestCondition
condition1
=
new
ParamsRequestCondition
(
"foo"
,
"bar"
,
"baz"
);
ParamsRequestCondition
condition2
=
new
ParamsRequestCondition
(
"foo"
,
"bar"
);
int
result
=
condition1
.
compareTo
(
condition2
);
int
result
=
condition1
.
compareTo
(
condition2
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition2
.
compareTo
(
condition1
);
result
=
condition2
.
compareTo
(
condition1
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
}
...
...
@@ -106,7 +112,7 @@ public class ParamsRequestConditionTests {
ParamsRequestCondition
condition2
=
new
ParamsRequestCondition
(
"foo=baz"
);
ParamsRequestCondition
result
=
condition1
.
combine
(
condition2
);
Set
<
ParamsRequestCondition
.
ParamRequestCondition
>
conditions
=
result
.
getConditions
();
Collection
<
ParamExpression
>
conditions
=
result
.
getContent
();
assertEquals
(
2
,
conditions
.
size
());
}
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/ProducesRequestConditionTests.java
浏览文件 @
96b0752d
...
...
@@ -16,17 +16,17 @@
package
org.springframework.web.servlet.mvc.method.condition
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Set
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
org.junit.Test
;
import
java.util.Collection
;
import
org.
springframework.http.MediaType
;
import
org.
junit.Test
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
static
org
.
junit
.
Assert
.*;
import
org.springframework.web.servlet.mvc.method.condition.ProducesRequestCondition.ProduceMediaTypeExpression
;
/**
* @author Arjen Poutsma
...
...
@@ -35,65 +35,66 @@ public class ProducesRequestConditionTests {
@Test
public
void
consumesMatch
()
{
RequestCondition
condition
=
new
ProducesRequestCondition
(
"text/plain"
);
Produces
RequestCondition
condition
=
new
ProducesRequestCondition
(
"text/plain"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/plain"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
negatedConsumesMatch
()
{
RequestCondition
condition
=
new
ProducesRequestCondition
(
"!text/plain"
);
Produces
RequestCondition
condition
=
new
ProducesRequestCondition
(
"!text/plain"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/plain"
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
consumesWildcardMatch
()
{
RequestCondition
condition
=
new
ProducesRequestCondition
(
"text/*"
);
Produces
RequestCondition
condition
=
new
ProducesRequestCondition
(
"text/*"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/plain"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
consumesMultipleMatch
()
{
RequestCondition
condition
=
new
ProducesRequestCondition
(
"text/plain"
,
"application/xml"
);
Produces
RequestCondition
condition
=
new
ProducesRequestCondition
(
"text/plain"
,
"application/xml"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/plain"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
consumesSingleNoMatch
()
{
RequestCondition
condition
=
new
ProducesRequestCondition
(
"text/plain"
);
Produces
RequestCondition
condition
=
new
ProducesRequestCondition
(
"text/plain"
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"application/xml"
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
compareToSingle
()
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/plain"
);
ProducesRequestCondition
condition1
=
new
ProducesRequestCondition
(
"text/plain"
);
ProducesRequestCondition
condition2
=
new
ProducesRequestCondition
(
"text/*"
);
List
<
MediaType
>
accept
=
Collections
.
singletonList
(
MediaType
.
TEXT_PLAIN
);
int
result
=
condition1
.
compareTo
(
condition2
,
accept
);
int
result
=
condition1
.
compareTo
(
condition2
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition2
.
compareTo
(
condition1
,
accep
t
);
result
=
condition2
.
compareTo
(
condition1
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
}
...
...
@@ -102,23 +103,25 @@ public class ProducesRequestConditionTests {
ProducesRequestCondition
condition1
=
new
ProducesRequestCondition
(
"*/*"
,
"text/plain"
);
ProducesRequestCondition
condition2
=
new
ProducesRequestCondition
(
"text/*"
,
"text/plain;q=0.7"
);
List
<
MediaType
>
accept
=
Collections
.
singletonList
(
MediaType
.
TEXT_PLAIN
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/plain"
);
int
result
=
condition1
.
compareTo
(
condition2
,
accep
t
);
int
result
=
condition1
.
compareTo
(
condition2
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition2
.
compareTo
(
condition1
,
accep
t
);
result
=
condition2
.
compareTo
(
condition1
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
condition1
=
new
ProducesRequestCondition
(
"*/*"
);
condition2
=
new
ProducesRequestCondition
(
"text/*"
);
accept
=
Collections
.
singletonList
(
new
MediaType
(
"text"
,
"*"
));
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/*"
);
result
=
condition1
.
compareTo
(
condition2
,
accep
t
);
result
=
condition1
.
compareTo
(
condition2
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
result
=
condition2
.
compareTo
(
condition1
,
accep
t
);
result
=
condition2
.
compareTo
(
condition1
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
}
...
...
@@ -127,20 +130,24 @@ public class ProducesRequestConditionTests {
ProducesRequestCondition
condition1
=
new
ProducesRequestCondition
(
"text/*"
,
"text/plain"
);
ProducesRequestCondition
condition2
=
new
ProducesRequestCondition
(
"application/*"
,
"application/xml"
);
List
<
MediaType
>
accept
=
Arrays
.
asList
(
MediaType
.
TEXT_PLAIN
,
MediaType
.
APPLICATION_XML
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/plain"
);
request
.
addHeader
(
"Accept"
,
"application/xml"
);
int
result
=
condition1
.
compareTo
(
condition2
,
accep
t
);
int
result
=
condition1
.
compareTo
(
condition2
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition2
.
compareTo
(
condition1
,
accep
t
);
result
=
condition2
.
compareTo
(
condition1
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
accept
=
Arrays
.
asList
(
MediaType
.
APPLICATION_XML
,
MediaType
.
TEXT_PLAIN
);
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"application/xml"
);
request
.
addHeader
(
"Accept"
,
"text/plain"
);
result
=
condition1
.
compareTo
(
condition2
,
accep
t
);
result
=
condition1
.
compareTo
(
condition2
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
result
=
condition2
.
compareTo
(
condition1
,
accep
t
);
result
=
condition2
.
compareTo
(
condition1
,
reques
t
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
}
...
...
@@ -166,28 +173,11 @@ public class ProducesRequestConditionTests {
public
void
parseConsumesAndHeaders
()
{
String
[]
consumes
=
new
String
[]
{
"text/plain"
};
String
[]
headers
=
new
String
[]{
"foo=bar"
,
"accept=application/xml,application/pdf"
};
ProducesRequestCondition
condition
=
RequestConditionFactory
.
parseProduces
(
consumes
,
headers
);
ProducesRequestCondition
condition
=
new
ProducesRequestCondition
(
consumes
,
headers
);
assertConditions
(
condition
,
"text/plain"
,
"application/xml"
,
"application/pdf"
);
}
@Test
public
void
parseConsumesDefault
()
{
String
[]
consumes
=
new
String
[]
{
"*/*"
};
String
[]
headers
=
new
String
[
0
];
ProducesRequestCondition
condition
=
RequestConditionFactory
.
parseProduces
(
consumes
,
headers
);
assertConditions
(
condition
,
"*/*"
);
}
@Test
public
void
parseConsumesDefaultAndHeaders
()
{
String
[]
consumes
=
new
String
[]
{
"*/*"
};
String
[]
headers
=
new
String
[]{
"foo=bar"
,
"accept=text/plain"
};
ProducesRequestCondition
condition
=
RequestConditionFactory
.
parseProduces
(
consumes
,
headers
);
assertConditions
(
condition
,
"text/plain"
);
}
@Test
public
void
getMatchingCondition
()
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
...
...
@@ -205,12 +195,12 @@ public class ProducesRequestConditionTests {
}
private
void
assertConditions
(
ProducesRequestCondition
condition
,
String
...
expected
)
{
Set
<
ProducesRequestCondition
.
ProduceRequestCondition
>
conditions
=
condition
.
getConditions
();
assertEquals
(
"Invalid amount of conditions"
,
condit
ions
.
size
(),
expected
.
length
);
Collection
<
ProduceMediaTypeExpression
>
expressions
=
condition
.
getContent
();
assertEquals
(
"Invalid amount of conditions"
,
express
ions
.
size
(),
expected
.
length
);
for
(
String
s
:
expected
)
{
boolean
found
=
false
;
for
(
Produce
sRequestCondition
.
ProduceRequestCondition
requestCondition
:
condit
ions
)
{
String
conditionMediaType
=
requestCondition
.
getMediaType
().
toString
();
for
(
Produce
MediaTypeExpression
expr
:
express
ions
)
{
String
conditionMediaType
=
expr
.
getMediaType
().
toString
();
if
(
conditionMediaType
.
equals
(
s
))
{
found
=
true
;
break
;
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestConditionTests.java
浏览文件 @
96b0752d
...
...
@@ -30,29 +30,29 @@ public class RequestMethodsRequestConditionTests {
@Test
public
void
methodMatch
()
{
RequestCondition
condition
=
new
RequestMethodsRequestCondition
(
RequestMethod
.
GET
);
Request
MethodsRequest
Condition
condition
=
new
RequestMethodsRequestCondition
(
RequestMethod
.
GET
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
methodNoMatch
()
{
RequestCondition
condition
=
new
RequestMethodsRequestCondition
(
RequestMethod
.
GET
);
Request
MethodsRequest
Condition
condition
=
new
RequestMethodsRequestCondition
(
RequestMethod
.
GET
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"POST"
,
"/foo"
);
assert
False
(
condition
.
match
(
request
));
assert
Null
(
condition
.
getMatchingCondition
(
request
));
}
@Test
public
void
multipleMethodsMatch
()
{
RequestCondition
condition
=
new
RequestMethodsRequestCondition
(
RequestMethod
.
GET
,
RequestMethod
.
POST
);
Request
MethodsRequest
Condition
condition
=
new
RequestMethodsRequestCondition
(
RequestMethod
.
GET
,
RequestMethod
.
POST
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
assert
True
(
condition
.
match
(
request
));
assert
NotNull
(
condition
.
getMatchingCondition
(
request
));
}
...
...
@@ -62,16 +62,18 @@ public class RequestMethodsRequestConditionTests {
RequestMethodsRequestCondition
condition2
=
new
RequestMethodsRequestCondition
(
RequestMethod
.
POST
);
RequestMethodsRequestCondition
condition3
=
new
RequestMethodsRequestCondition
();
int
result
=
condition1
.
compareTo
(
condition2
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
();
int
result
=
condition1
.
compareTo
(
condition2
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition2
.
compareTo
(
condition1
);
result
=
condition2
.
compareTo
(
condition1
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
result
=
condition2
.
compareTo
(
condition3
);
result
=
condition2
.
compareTo
(
condition3
,
request
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
<
0
);
result
=
condition1
.
compareTo
(
condition1
);
result
=
condition1
.
compareTo
(
condition1
,
request
);
assertEquals
(
"Invalid comparison result "
,
0
,
result
);
}
...
...
@@ -81,7 +83,7 @@ public class RequestMethodsRequestConditionTests {
RequestMethodsRequestCondition
condition2
=
new
RequestMethodsRequestCondition
(
RequestMethod
.
POST
);
RequestMethodsRequestCondition
result
=
condition1
.
combine
(
condition2
);
assertEquals
(
2
,
result
.
getCon
ditions
().
size
());
assertEquals
(
2
,
result
.
getCon
tent
().
size
());
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录