Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
4826cae0
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
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,发现更多精彩内容 >>
提交
4826cae0
编写于
6月 17, 2011
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SPR-7812 Add CustomRequestCondition
上级
7dd69329
变更
16
显示空白变更内容
内联
并排
Showing
16 changed file
with
408 addition
and
240 deletion
+408
-240
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
...ork/web/servlet/handler/AbstractHandlerMethodMapping.java
+4
-6
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java
...gframework/web/servlet/mvc/method/RequestMappingInfo.java
+134
-66
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java
.../servlet/mvc/method/RequestMappingInfoHandlerMapping.java
+43
-69
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
...t/mvc/method/annotation/RequestMappingHandlerMapping.java
+12
-14
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/AbstractRequestCondition.java
...ervlet/mvc/method/condition/AbstractRequestCondition.java
+6
-11
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ConsumesRequestCondition.java
...ervlet/mvc/method/condition/ConsumesRequestCondition.java
+10
-10
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/CustomRequestCondition.java
.../servlet/mvc/method/condition/CustomRequestCondition.java
+132
-0
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestCondition.java
...servlet/mvc/method/condition/HeadersRequestCondition.java
+4
-4
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestCondition.java
.../servlet/mvc/method/condition/ParamsRequestCondition.java
+4
-4
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/PatternsRequestCondition.java
...ervlet/mvc/method/condition/PatternsRequestCondition.java
+5
-5
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ProducesRequestCondition.java
...ervlet/mvc/method/condition/ProducesRequestCondition.java
+5
-5
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition.java
...rk/web/servlet/mvc/method/condition/RequestCondition.java
+7
-5
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestCondition.java
.../mvc/method/condition/RequestMethodsRequestCondition.java
+5
-5
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java
...mework/web/servlet/handler/HandlerMethodMappingTests.java
+7
-2
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoComparatorTests.java
...servlet/mvc/method/RequestMappingInfoComparatorTests.java
+11
-15
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java
...ework/web/servlet/mvc/method/RequestMappingInfoTests.java
+19
-19
未找到文件。
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
浏览文件 @
4826cae0
...
...
@@ -257,14 +257,14 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
List
<
Match
>
matches
=
new
ArrayList
<
Match
>();
for
(
T
mapping
:
mappings
)
{
T
match
=
getMatchingMapping
(
mapping
,
lookupPath
,
request
);
T
match
=
getMatchingMapping
(
mapping
,
request
);
if
(
match
!=
null
)
{
matches
.
add
(
new
Match
(
match
,
handlerMethods
.
get
(
mapping
)));
}
}
if
(!
matches
.
isEmpty
())
{
Comparator
<
Match
>
comparator
=
new
MatchComparator
(
getMappingComparator
(
lookupPath
,
request
));
Comparator
<
Match
>
comparator
=
new
MatchComparator
(
getMappingComparator
(
request
));
Collections
.
sort
(
matches
,
comparator
);
if
(
logger
.
isTraceEnabled
())
{
...
...
@@ -309,20 +309,18 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
* will contain only 1).
*
* @param mapping the mapping to get a match for
* @param lookupPath mapping lookup path within the current servlet mapping if applicable
* @param request the current HTTP servlet request
* @return a matching mapping, or {@code null} if the given mapping does not match the request
*/
protected
abstract
T
getMatchingMapping
(
T
mapping
,
String
lookupPath
,
HttpServletRequest
request
);
protected
abstract
T
getMatchingMapping
(
T
mapping
,
HttpServletRequest
request
);
/**
* Returns a comparator to sort request mappings with. The returned comparator should sort 'better' matches higher.
*
* @param lookupPath mapping lookup path within the current servlet mapping if applicable
* @param request the current HTTP servlet request
* @return the comparator
*/
protected
abstract
Comparator
<
T
>
getMappingComparator
(
String
lookupPath
,
HttpServletRequest
request
);
protected
abstract
Comparator
<
T
>
getMappingComparator
(
HttpServletRequest
request
);
/**
* Invoked when no match was found. Default implementation returns {@code null}.
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java
浏览文件 @
4826cae0
...
...
@@ -18,17 +18,29 @@ package org.springframework.web.servlet.mvc.method;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.util.PathMatcher
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.servlet.mvc.method.condition.ConsumesRequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.CustomRequestCondition
;
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.RequestCondition
;
import
org.springframework.web.servlet.mvc.method.condition.RequestMethodsRequestCondition
;
/**
* Contains request mapping conditions to be matched to a given request.
* A RequestMapingInfo encapsulates and operates on the following request mapping conditions:
* <ul>
* <li>{@link PatternsRequestCondition}</li>
* <li>{@link RequestMethodsRequestCondition}</li>
* <li>{@link ParamsRequestCondition}</li>
* <li>{@link HeadersRequestCondition}</li>
* <li>{@link ConsumesRequestCondition}</li>
* <li>{@link ProducesRequestCondition}</li>
* </ul>
*
* Optionally a custom request condition may also be provided by wrapping it in an instance
* of {@link CustomRequestCondition}.
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
...
...
@@ -48,130 +60,183 @@ public final class RequestMappingInfo {
private
final
ProducesRequestCondition
producesCondition
;
private
CustomRequestCondition
customCondition
=
new
CustomRequestCondition
();
private
int
hash
;
/**
* Creates a new {@code RequestMappingInfo} instance.
*/
public
RequestMappingInfo
(
PatternsRequestCondition
patternsCondition
,
RequestMethodsRequestCondition
methodsCondition
,
ParamsRequestCondition
paramsCondition
,
HeadersRequestCondition
headersCondition
,
ConsumesRequestCondition
consumesCondition
,
ProducesRequestCondition
producesCondition
)
{
this
.
patternsCondition
=
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
();
this
.
consumesCondition
=
consumesCondition
!=
null
?
consumesCondition
:
new
ConsumesRequestCondition
();
this
.
producesCondition
=
producesCondition
!=
null
?
producesCondition
:
new
ProducesRequestCondition
();
public
RequestMappingInfo
(
PatternsRequestCondition
patterns
,
RequestMethodsRequestCondition
methods
,
ParamsRequestCondition
params
,
HeadersRequestCondition
headers
,
ConsumesRequestCondition
consumes
,
ProducesRequestCondition
produces
)
{
this
(
patterns
,
methods
,
params
,
headers
,
consumes
,
produces
,
null
);
}
/**
* Creates a new {@code RequestMappingInfo} instance also providing a custom {@link RequestCondition}.
*/
public
RequestMappingInfo
(
PatternsRequestCondition
patterns
,
RequestMethodsRequestCondition
methods
,
ParamsRequestCondition
params
,
HeadersRequestCondition
headers
,
ConsumesRequestCondition
consumes
,
ProducesRequestCondition
produces
,
CustomRequestCondition
custom
)
{
this
.
patternsCondition
=
patterns
!=
null
?
patterns
:
new
PatternsRequestCondition
();
this
.
methodsCondition
=
methods
!=
null
?
methods
:
new
RequestMethodsRequestCondition
();
this
.
paramsCondition
=
params
!=
null
?
params
:
new
ParamsRequestCondition
();
this
.
headersCondition
=
headers
!=
null
?
headers
:
new
HeadersRequestCondition
();
this
.
consumesCondition
=
consumes
!=
null
?
consumes
:
new
ConsumesRequestCondition
();
this
.
producesCondition
=
produces
!=
null
?
produces
:
new
ProducesRequestCondition
();
this
.
customCondition
=
custom
!=
null
?
custom
:
new
CustomRequestCondition
();
}
/**
* Package protected
, used for testing
.
* Package protected
constructor for tests
.
*/
RequestMappingInfo
(
String
[]
patterns
,
RequestMethod
...
methods
)
{
this
(
new
PatternsRequestCondition
(
patterns
),
new
RequestMethodsRequestCondition
(
methods
),
null
,
null
,
null
,
null
);
}
/**
* Returns the patterns of this request mapping info.
* Returns the
URL
patterns of this request mapping info.
*/
public
PatternsRequestCondition
getPatternsCondition
()
{
return
patternsCondition
;
}
/**
* Returns the
request method condition of this request mapping info
.
* Returns the
HTTP request methods of this {@link RequestMappingInfo}
.
*/
public
RequestMethodsRequestCondition
getMethodsCondition
()
{
return
methodsCondition
;
}
/**
* Returns the
request parameters condition of this request mapping info
.
* Returns the
"parameters" condition of this {@link RequestMappingInfo}
.
*/
public
ParamsRequestCondition
getParamsCondition
()
{
return
paramsCondition
;
}
/**
* Returns the
request headers condition of this request mapping info
.
* Returns the
"headers" condition of this {@link RequestMappingInfo}
.
*/
public
HeadersRequestCondition
getHeadersCondition
()
{
return
headersCondition
;
}
/**
* Returns the
request consumes condition of this request mapping info
.
* Returns the
"consumes" condition of this {@link RequestMappingInfo}
.
*/
public
ConsumesRequestCondition
getConsumesCondition
()
{
return
consumesCondition
;
}
/**
* Returns the
request produces condition of this request mapping info
.
* Returns the
"produces" condition of this {@link RequestMappingInfo}
.
*/
public
ProducesRequestCondition
getProducesCondition
()
{
return
producesCondition
;
}
/**
* Combines this {@code RequestMappingInfo} with another as follows:
* <ul>
* <li>URL patterns:
* <ul>
* <li>If both have patterns combine them according to the rules of the given {@link PathMatcher}
* <li>If either contains patterns, but not both, use the available pattern
* <li>If neither contains patterns use ""
* </ul>
* <li>HTTP methods are combined as union of all HTTP methods listed in both keys.
* <li>Request parameters are combined as per {@link ParamsRequestCondition#combine(ParamsRequestCondition)}.
* <li>Request headers are combined as per {@link HeadersRequestCondition#combine(HeadersRequestCondition)}.
* <li>Consumes are combined as per {@link ConsumesRequestCondition#combine(ConsumesRequestCondition)}.
* </ul>
* @param methodKey the key to combine with
* @return a new request mapping info containing conditions from both keys
* Sets a custom request condition.
*/
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
);
public
void
setCustomCondition
(
CustomRequestCondition
customCondition
)
{
this
.
customCondition
=
customCondition
;
}
return
new
RequestMappingInfo
(
patterns
,
methods
,
params
,
headers
,
consumes
,
produces
);
/**
* Combines "this" request mapping info (i.e. the current instance) with another request mapping info instance.
* <p>Example: combine type- and method-level request mappings.
* @return a new request mapping info instance; never {@code null}
*/
public
RequestMappingInfo
combine
(
RequestMappingInfo
other
)
{
PatternsRequestCondition
patterns
=
this
.
patternsCondition
.
combine
(
other
.
patternsCondition
);
RequestMethodsRequestCondition
methods
=
this
.
methodsCondition
.
combine
(
other
.
methodsCondition
);
ParamsRequestCondition
params
=
this
.
paramsCondition
.
combine
(
other
.
paramsCondition
);
HeadersRequestCondition
headers
=
this
.
headersCondition
.
combine
(
other
.
headersCondition
);
ConsumesRequestCondition
consumes
=
this
.
consumesCondition
.
combine
(
other
.
consumesCondition
);
ProducesRequestCondition
produces
=
this
.
producesCondition
.
combine
(
other
.
producesCondition
);
CustomRequestCondition
custom
=
this
.
customCondition
.
combine
(
other
.
customCondition
);
return
new
RequestMappingInfo
(
patterns
,
methods
,
params
,
headers
,
consumes
,
produces
,
custom
);
}
/**
* 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
* @return a new request mapping info that contains all matching attributes, or {@code null} if not all conditions match
* Checks if all conditions in this request mapping info match the provided request and returns
* a potentially new request mapping info with conditions tailored to the current request.
* <p>For example the returned instance may contain the subset of URL patterns that match to
* the current request, sorted with best matching patterns on top.
* @return a new instance in case all conditions match; or {@code null} otherwise
*/
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
)
{
public
RequestMappingInfo
getMatchingRequestMappingInfo
(
HttpServletRequest
request
)
{
RequestMethodsRequestCondition
methods
=
methodsCondition
.
getMatchingCondition
(
request
);
ParamsRequestCondition
params
=
paramsCondition
.
getMatchingCondition
(
request
);
HeadersRequestCondition
headers
=
headersCondition
.
getMatchingCondition
(
request
);
ConsumesRequestCondition
consumes
=
consumesCondition
.
getMatchingCondition
(
request
);
ProducesRequestCondition
produces
=
producesCondition
.
getMatchingCondition
(
request
);
if
(
methods
==
null
||
params
==
null
||
headers
==
null
||
consumes
==
null
||
produces
==
null
)
{
return
null
;
}
PatternsRequestCondition
matchingPatterns
=
patternsCondition
.
getMatchingCondition
(
request
);
if
(
matchingPatterns
!=
null
)
{
return
new
RequestMappingInfo
(
matchingPatterns
,
matchingMethod
,
matchingParams
,
matchingHeaders
,
matchingConsumes
,
matchingProduces
);
PatternsRequestCondition
patterns
=
patternsCondition
.
getMatchingCondition
(
request
);
if
(
patterns
==
null
)
{
return
null
;
}
CustomRequestCondition
custom
=
customCondition
.
getMatchingCondition
(
request
);
if
(
custom
==
null
)
{
return
null
;
}
return
new
RequestMappingInfo
(
patterns
,
methods
,
params
,
headers
,
consumes
,
produces
,
custom
);
}
/**
* Compares "this" info (i.e. the current instance) with another info in the context of a request.
* <p>Note: it is assumed both instances have been obtained via
* {@link #getMatchingRequestMappingInfo(HttpServletRequest)} to ensure they have conditions with
* content relevant to current request.
*/
public
int
compareTo
(
RequestMappingInfo
other
,
HttpServletRequest
request
)
{
int
result
=
patternsCondition
.
compareTo
(
other
.
getPatternsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
paramsCondition
.
compareTo
(
other
.
getParamsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
headersCondition
.
compareTo
(
other
.
getHeadersCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
consumesCondition
.
compareTo
(
other
.
getConsumesCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
producesCondition
.
compareTo
(
other
.
getProducesCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
methodsCondition
.
compareTo
(
other
.
getMethodsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
customCondition
.
compareTo
(
other
.
customCondition
,
request
);
if
(
result
!=
0
)
{
return
result
;
}
return
0
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
...
...
@@ -184,7 +249,8 @@ public final class RequestMappingInfo {
this
.
paramsCondition
.
equals
(
other
.
paramsCondition
)
&&
this
.
headersCondition
.
equals
(
other
.
headersCondition
)
&&
this
.
consumesCondition
.
equals
(
other
.
consumesCondition
)
&&
this
.
producesCondition
.
equals
(
other
.
producesCondition
));
this
.
producesCondition
.
equals
(
other
.
producesCondition
)
&&
this
.
customCondition
.
equals
(
other
.
customCondition
));
}
return
false
;
}
...
...
@@ -199,6 +265,7 @@ public final class RequestMappingInfo {
result
=
31
*
result
+
headersCondition
.
hashCode
();
result
=
31
*
result
+
consumesCondition
.
hashCode
();
result
=
31
*
result
+
producesCondition
.
hashCode
();
result
=
31
*
result
+
customCondition
.
hashCode
();
hash
=
result
;
}
return
result
;
...
...
@@ -213,6 +280,7 @@ public final class RequestMappingInfo {
builder
.
append
(
",headers="
).
append
(
headersCondition
);
builder
.
append
(
",consumes="
).
append
(
consumesCondition
);
builder
.
append
(
",produces="
).
append
(
producesCondition
);
builder
.
append
(
",custom="
).
append
(
customCondition
);
builder
.
append
(
'}'
);
return
builder
.
toString
();
}
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java
浏览文件 @
4826cae0
...
...
@@ -27,7 +27,6 @@ import javax.servlet.ServletException;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.PathMatcher
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.HttpMediaTypeNotSupportedException
;
...
...
@@ -53,34 +52,47 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
while
(
mappings
.
size
()
>
1
)
{
RequestMappingInfo
mapping
=
mappings
.
remove
(
0
);
for
(
RequestMappingInfo
otherMapping
:
mappings
)
{
// further validate mapping conditions
//
TODO:
further validate mapping conditions
}
}
}
/**
* Get the URL paths associated with this {@link RequestMappingInfo}.
*/
@Override
protected
Set
<
String
>
getMappingPaths
(
RequestMappingInfo
mapping
)
{
return
mapping
.
getPatternsCondition
().
getPatterns
();
Set
<
String
>
paths
=
new
HashSet
<
String
>();
for
(
String
pattern
:
mapping
.
getPatternsCondition
().
getPatterns
())
{
if
(!
getPathMatcher
().
isPattern
(
pattern
))
{
paths
.
add
(
pattern
);
}
}
return
paths
;
}
/**
* Returns a new {@link RequestMappingInfo} with attributes matching to the current request or {@code null}.
* Checks if the given RequestMappingInfo matches the current request and returns a potentially new
* RequestMappingInfo instances tailored to the current request, for example containing the subset
* of URL patterns or media types that match the request.
*
* @
see RequestMappingInfo#getMatchingRequestMapping(String, HttpServletRequest, PathMatcher)
* @
returns a RequestMappingInfo instance in case of a match; or {@code null} in case of no match.
*/
@Override
protected
RequestMappingInfo
getMatchingMapping
(
RequestMappingInfo
mapping
,
String
lookupPath
,
HttpServletRequest
request
)
{
return
mapping
.
getMatchingRequestMapping
(
request
);
protected
RequestMappingInfo
getMatchingMapping
(
RequestMappingInfo
mapping
,
HttpServletRequest
request
)
{
return
mapping
.
getMatchingRequestMappingInfo
(
request
);
}
/**
* Returns a {@link Comparator}
that can be used to sort and select the best matching {@link RequestMappingInfo}
.
* Returns a {@link Comparator}
for sorting {@link RequestMappingInfo} in the context of the given request
.
*/
@Override
protected
Comparator
<
RequestMappingInfo
>
getMappingComparator
(
String
lookupPath
,
HttpServletRequest
request
)
{
return
new
RequestMappingInfoComparator
(
request
);
protected
Comparator
<
RequestMappingInfo
>
getMappingComparator
(
final
HttpServletRequest
request
)
{
return
new
Comparator
<
RequestMappingInfo
>()
{
public
int
compare
(
RequestMappingInfo
info
,
RequestMappingInfo
otherInfo
)
{
return
info
.
compareTo
(
otherInfo
,
request
);
}
};
}
/**
...
...
@@ -106,7 +118,12 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
/**
* Iterates all {@link RequestMappingInfo}s looking for mappings that match by URL but not by HTTP method.
*
* @throws HttpRequestMethodNotSupportedException if there are matches by URL but not by HTTP method
* @throws HttpRequestMethodNotSupportedException
* if there are matches by URL but not by HTTP method
* @throws HttpMediaTypeNotAcceptableException
* if there are matches by URL but the consumable media types don't match the 'Content-Type' header
* @throws HttpMediaTypeNotAcceptableException
* if there are matches by URL but the producible media types don't match the 'Accept' header
*/
@Override
protected
HandlerMethod
handleNoMatch
(
Set
<
RequestMappingInfo
>
requestMappingInfos
,
...
...
@@ -116,8 +133,7 @@ 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
.
getPatternsCondition
().
getPatterns
())
{
if
(
getPathMatcher
().
match
(
pattern
,
lookupPath
))
{
if
(
info
.
getPatternsCondition
().
getMatchingCondition
(
request
)
!=
null
)
{
if
(
info
.
getMethodsCondition
().
getMatchingCondition
(
request
)
==
null
)
{
for
(
RequestMethod
method
:
info
.
getMethodsCondition
().
getMethods
())
{
allowedMethods
.
add
(
method
.
name
());
...
...
@@ -131,7 +147,6 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
}
}
}
}
if
(!
allowedMethods
.
isEmpty
())
{
throw
new
HttpRequestMethodNotSupportedException
(
request
.
getMethod
(),
allowedMethods
);
}
...
...
@@ -150,45 +165,4 @@ 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 only a subset of URL patterns may apply to the current request.
*/
private
class
RequestMappingInfoComparator
implements
Comparator
<
RequestMappingInfo
>
{
private
final
HttpServletRequest
request
;
public
RequestMappingInfoComparator
(
HttpServletRequest
request
)
{
this
.
request
=
request
;
}
public
int
compare
(
RequestMappingInfo
mapping
,
RequestMappingInfo
otherMapping
)
{
int
result
=
mapping
.
getPatternsCondition
().
compareTo
(
otherMapping
.
getPatternsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getParamsCondition
().
compareTo
(
otherMapping
.
getParamsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getHeadersCondition
().
compareTo
(
otherMapping
.
getHeadersCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getConsumesCondition
().
compareTo
(
otherMapping
.
getConsumesCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getProducesCondition
().
compareTo
(
otherMapping
.
getProducesCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
result
=
mapping
.
getMethodsCondition
().
compareTo
(
otherMapping
.
getMethodsCondition
(),
request
);
if
(
result
!=
0
)
{
return
result
;
}
return
0
;
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
浏览文件 @
4826cae0
...
...
@@ -37,7 +37,7 @@ import org.springframework.web.servlet.mvc.method.condition.RequestMethodsReques
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @since 3.1
.0
* @since 3.1
*/
public
class
RequestMappingHandlerMapping
extends
RequestMappingInfoHandlerMapping
{
...
...
@@ -62,20 +62,18 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
*/
@Override
protected
RequestMappingInfo
getMappingForMethod
(
Method
method
,
Class
<?>
handlerType
)
{
RequestMapping
annotation
=
AnnotationUtils
.
findAnnotation
(
method
,
RequestMapping
.
class
);
if
(
annotation
!=
null
)
{
RequestMappingInfo
methodMapping
=
createFromRequestMapping
(
annotation
);
RequestMapping
typeAnnot
=
AnnotationUtils
.
findAnnotation
(
handlerType
,
RequestMapping
.
class
);
if
(
typeAnnot
!=
null
)
{
RequestMappingInfo
typeMapping
=
createFromRequestMapping
(
typeAnnot
);
return
typeMapping
.
combine
(
methodMapping
);
}
else
{
return
methodMapping
;
RequestMapping
methodAnnotation
=
AnnotationUtils
.
findAnnotation
(
method
,
RequestMapping
.
class
);
if
(
methodAnnotation
==
null
)
{
return
null
;
}
RequestMappingInfo
methodInfo
=
createFromRequestMapping
(
methodAnnotation
);
RequestMapping
typeAnnotation
=
AnnotationUtils
.
findAnnotation
(
handlerType
,
RequestMapping
.
class
);
if
(
typeAnnotation
!=
null
)
{
RequestMappingInfo
typeInfo
=
createFromRequestMapping
(
typeAnnotation
);
return
typeInfo
.
combine
(
methodInfo
);
}
else
{
return
null
;
return
methodInfo
;
}
}
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/
RequestConditionSupport
.java
→
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/
AbstractRequestCondition
.java
浏览文件 @
4826cae0
...
...
@@ -25,11 +25,11 @@ import java.util.Iterator;
* @author Rossen Stoyanchev
* @since 3.1
*/
abstract
class
RequestConditionSupport
<
This
extends
RequestConditionSupport
<
This
>>
implements
RequestCondition
<
This
>
{
abstract
class
AbstractRequestCondition
<
T
extends
AbstractRequestCondition
<
T
>>
implements
RequestCondition
<
T
>
{
/**
* Returns the
individual expressions a request condition is composed of such as
*
URL patterns, HTTP request methods, parameter expressions, etc.
* Returns the
discrete expressions a request condition is composed of such as URL patterns,
*
HTTP request methods, parameter expressions, etc.
*/
protected
abstract
Collection
<?>
getContent
();
...
...
@@ -39,7 +39,7 @@ abstract class RequestConditionSupport<This extends RequestConditionSupport<This
return
true
;
}
if
(
o
!=
null
&&
getClass
().
equals
(
o
.
getClass
()))
{
RequestConditionSupport
<?>
other
=
(
RequestConditionSupport
<?>)
o
;
AbstractRequestCondition
<?>
other
=
(
AbstractRequestCondition
<?>)
o
;
return
getContent
().
equals
(
other
.
getContent
());
}
return
false
;
...
...
@@ -57,12 +57,7 @@ abstract class RequestConditionSupport<This extends RequestConditionSupport<This
Object
expression
=
iterator
.
next
();
builder
.
append
(
expression
.
toString
());
if
(
iterator
.
hasNext
())
{
if
(
isLogicalConjunction
())
{
builder
.
append
(
" && "
);
}
else
{
builder
.
append
(
" || "
);
}
builder
.
append
(
getToStringInfix
());
}
}
builder
.
append
(
"]"
);
...
...
@@ -73,6 +68,6 @@ abstract class RequestConditionSupport<This extends RequestConditionSupport<This
* Returns {@code true} if the individual expressions of the condition are combined via logical
* conjunction (" && "); or {@code false} otherwise.
*/
protected
abstract
boolean
isLogicalConjunction
();
protected
abstract
String
getToStringInfix
();
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ConsumesRequestCondition.java
浏览文件 @
4826cae0
...
...
@@ -44,13 +44,13 @@ import org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondit
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
ConsumesRequestCondition
extends
RequestConditionSupport
<
ConsumesRequestCondition
>
{
public
class
ConsumesRequestCondition
extends
AbstractRequestCondition
<
ConsumesRequestCondition
>
{
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
* @param consumes the expressions to parse; if 0
,
the condition matches to every request
*/
public
ConsumesRequestCondition
(
String
...
consumes
)
{
this
(
consumes
,
null
);
...
...
@@ -60,8 +60,8 @@ public class ConsumesRequestCondition extends RequestConditionSupport<ConsumesRe
* 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
* @param consumes the consumes expressions to parse;
if 0, the condition
matches to all requests
* @param headers the header expression to parse;
if 0, the condition
matches to all requests
*/
public
ConsumesRequestCondition
(
String
[]
consumes
,
String
[]
headers
)
{
this
(
parseExpressions
(
consumes
,
headers
));
...
...
@@ -119,12 +119,12 @@ public class ConsumesRequestCondition extends RequestConditionSupport<ConsumesRe
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
false
;
protected
String
getToStringInfix
()
{
return
" || "
;
}
/**
* Returns the "other" instance
as long as it contains any expressions; or
"this" instance otherwise.
* Returns the "other" instance
provided it contains expressions; returns
"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.
*/
...
...
@@ -133,13 +133,13 @@ public class ConsumesRequestCondition extends RequestConditionSupport<ConsumesRe
}
/**
* 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.
* Checks if any of the consumable media type expressions match the given request and returns an
* i
nstance that i
s 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.
* or a new condition with matching expressions
only
; or {@code null} if no expressions match.
*/
public
ConsumesRequestCondition
getMatchingCondition
(
HttpServletRequest
request
)
{
if
(
isEmpty
())
{
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/CustomRequestCondition.java
0 → 100644
浏览文件 @
4826cae0
/*
* 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.Collections
;
import
javax.servlet.http.HttpServletRequest
;
/**
* Wraps and delegates operations to a custom {@link RequestCondition} whose type is not known and even its
* presence is not guaranteed ahead of time. The main purpose of this class is to ensure a type-safe and
* null-safe way of combining and comparing custom request conditions.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public
final
class
CustomRequestCondition
extends
AbstractRequestCondition
<
CustomRequestCondition
>
{
@SuppressWarnings
(
"rawtypes"
)
private
final
RequestCondition
customCondition
;
/**
* Creates a {@link CustomRequestCondition} that wraps the given {@link RequestCondition} instance.
* @param requestCondition the custom request condition to wrap
*/
public
CustomRequestCondition
(
RequestCondition
<?>
requestCondition
)
{
this
.
customCondition
=
requestCondition
;
}
/**
* Creates an empty {@link CustomRequestCondition}.
*/
public
CustomRequestCondition
()
{
this
(
null
);
}
public
RequestCondition
<?>
getRequestCondition
()
{
return
customCondition
;
}
@Override
protected
Collection
<?>
getContent
()
{
return
customCondition
!=
null
?
Collections
.
singleton
(
customCondition
)
:
Collections
.
emptyList
();
}
@Override
protected
String
getToStringInfix
()
{
return
""
;
}
/**
* Delegates the operation to the wrapped custom request conditions. May also return "this" instance
* if the "other" does not contain a custom request condition and vice versa.
*/
@SuppressWarnings
(
"unchecked"
)
public
CustomRequestCondition
combine
(
CustomRequestCondition
other
)
{
if
(
customCondition
==
null
&&
other
.
customCondition
==
null
)
{
return
this
;
}
else
if
(
customCondition
==
null
)
{
return
other
;
}
else
if
(
other
.
customCondition
==
null
)
{
return
this
;
}
else
{
assertCompatible
(
other
);
RequestCondition
<?>
combined
=
(
RequestCondition
<?>)
customCondition
.
combine
(
other
.
customCondition
);
return
new
CustomRequestCondition
(
combined
);
}
}
private
void
assertCompatible
(
CustomRequestCondition
other
)
{
if
(
customCondition
!=
null
&&
other
.
customCondition
!=
null
)
{
Class
<?>
clazz
=
customCondition
.
getClass
();
Class
<?>
otherClazz
=
other
.
customCondition
.
getClass
();
if
(!
clazz
.
equals
(
otherClazz
))
{
throw
new
ClassCastException
(
"Incompatible custom request conditions: "
+
clazz
+
", "
+
otherClazz
);
}
}
}
/**
* Delegates the operation to the wrapped custom request condition; or otherwise returns the same
* instance if there is no custom request condition.
*/
public
CustomRequestCondition
getMatchingCondition
(
HttpServletRequest
request
)
{
if
(
customCondition
==
null
)
{
return
this
;
}
RequestCondition
<?>
match
=
(
RequestCondition
<?>)
customCondition
.
getMatchingCondition
(
request
);
return
new
CustomRequestCondition
(
match
);
}
/**
* Delegates the operation to the wrapped custom request conditions after checking for the presence
* custom request conditions and asserting type safety. The presence of a custom request condition
* in one instance but not the other will cause it to be selected, and vice versa.
*/
@SuppressWarnings
(
"unchecked"
)
public
int
compareTo
(
CustomRequestCondition
other
,
HttpServletRequest
request
)
{
if
(
customCondition
==
null
&&
other
.
customCondition
==
null
)
{
return
0
;
}
else
if
(
customCondition
==
null
)
{
return
1
;
}
else
if
(
other
.
customCondition
==
null
)
{
return
-
1
;
}
else
{
assertCompatible
(
other
);
return
customCondition
.
compareTo
(
other
.
customCondition
,
request
);
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestCondition.java
浏览文件 @
4826cae0
...
...
@@ -39,7 +39,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
HeadersRequestCondition
extends
RequestConditionSupport
<
HeadersRequestCondition
>
{
public
class
HeadersRequestCondition
extends
AbstractRequestCondition
<
HeadersRequestCondition
>
{
private
final
Set
<
HeaderExpression
>
expressions
;
...
...
@@ -50,7 +50,7 @@ public class HeadersRequestCondition extends RequestConditionSupport<HeadersRequ
* 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.
* @param headers 0 or more header expressions; if 0
,
the condition will match to every request.
*/
public
HeadersRequestCondition
(
String
...
headers
)
{
this
(
parseExpressions
(
headers
));
...
...
@@ -80,8 +80,8 @@ public class HeadersRequestCondition extends RequestConditionSupport<HeadersRequ
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
true
;
protected
String
getToStringInfix
()
{
return
" && "
;
}
/**
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestCondition.java
浏览文件 @
4826cae0
...
...
@@ -36,14 +36,14 @@ import org.springframework.web.util.WebUtils;
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
ParamsRequestCondition
extends
RequestConditionSupport
<
ParamsRequestCondition
>
{
public
class
ParamsRequestCondition
extends
AbstractRequestCondition
<
ParamsRequestCondition
>
{
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.
* @param params 0 or more param expressions; if 0
,
the condition will match to every request.
*/
public
ParamsRequestCondition
(
String
...
params
)
{
this
(
parseExpressions
(
params
));
...
...
@@ -69,8 +69,8 @@ public class ParamsRequestCondition extends RequestConditionSupport<ParamsReques
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
true
;
protected
String
getToStringInfix
()
{
return
" && "
;
}
/**
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/PatternsRequestCondition.java
浏览文件 @
4826cae0
...
...
@@ -41,7 +41,7 @@ import org.springframework.web.util.UrlPathHelper;
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
PatternsRequestCondition
extends
RequestConditionSupport
<
PatternsRequestCondition
>
{
public
class
PatternsRequestCondition
extends
AbstractRequestCondition
<
PatternsRequestCondition
>
{
private
final
Set
<
String
>
patterns
;
...
...
@@ -62,7 +62,7 @@ public class PatternsRequestCondition extends RequestConditionSupport<PatternsRe
* 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 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
*/
...
...
@@ -107,8 +107,8 @@ public class PatternsRequestCondition extends RequestConditionSupport<PatternsRe
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
false
;
protected
String
getToStringInfix
()
{
return
" || "
;
}
/**
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ProducesRequestCondition.java
浏览文件 @
4826cae0
...
...
@@ -44,7 +44,7 @@ import org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondit
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
ProducesRequestCondition
extends
RequestConditionSupport
<
ProducesRequestCondition
>
{
public
class
ProducesRequestCondition
extends
AbstractRequestCondition
<
ProducesRequestCondition
>
{
private
final
List
<
ProduceMediaTypeExpression
>
expressions
;
...
...
@@ -60,8 +60,8 @@ public class ProducesRequestCondition extends RequestConditionSupport<ProducesRe
* 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
* @param produces the produces expressions to parse
; if 0, the condition matches to all requests
* @param headers the header expression to parse
; if 0, the condition matches to all requests
*/
public
ProducesRequestCondition
(
String
[]
produces
,
String
[]
headers
)
{
this
(
parseExpressions
(
produces
,
headers
));
...
...
@@ -119,8 +119,8 @@ public class ProducesRequestCondition extends RequestConditionSupport<ProducesRe
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
false
;
protected
String
getToStringInfix
()
{
return
" || "
;
}
/**
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestCondition.java
浏览文件 @
4826cae0
...
...
@@ -24,11 +24,13 @@ import javax.servlet.http.HttpServletRequest;
* <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.
*
* @param <T> The type of objects that this RequestCondition can be compared to and combined with.
*
* @author Rossen Stoyanchev
* @author Arjen Poutsma
* @since 3.1
*/
public
interface
RequestCondition
<
T
his
extends
RequestCondition
<
This
>
>
{
public
interface
RequestCondition
<
T
>
{
/**
* Defines the rules for combining "this" condition (i.e. the current instance) with another condition.
...
...
@@ -36,7 +38,7 @@ public interface RequestCondition<This extends RequestCondition<This>> {
*
* @returns a request condition instance that is the result of combining the two condition instances.
*/
T
his
combine
(
This
other
);
T
combine
(
T
other
);
/**
* Checks if this condition matches the provided request and returns a potentially new request condition
...
...
@@ -45,13 +47,13 @@ public interface RequestCondition<This extends RequestCondition<This>> {
*
* @return a condition instance in case of a match; or {@code null} if there is no match.
*/
T
his
getMatchingCondition
(
HttpServletRequest
request
);
T
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)}
* <p>Note: it is assumed
both
instances have been obtained via {@link #getMatchingCondition(HttpServletRequest)}
* to ensure they have content relevant to current request only.
*/
int
compareTo
(
T
his
other
,
HttpServletRequest
request
);
int
compareTo
(
T
other
,
HttpServletRequest
request
);
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestCondition.java
浏览文件 @
4826cae0
...
...
@@ -36,13 +36,13 @@ import org.springframework.web.bind.annotation.RequestMethod;
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
RequestMethodsRequestCondition
extends
RequestConditionSupport
<
RequestMethodsRequestCondition
>
{
public
class
RequestMethodsRequestCondition
extends
AbstractRequestCondition
<
RequestMethodsRequestCondition
>
{
private
final
Set
<
RequestMethod
>
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.
* Create a {@link RequestMethodsRequestCondition} with the given
request method
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
));
...
...
@@ -72,8 +72,8 @@ public class RequestMethodsRequestCondition extends RequestConditionSupport<Requ
}
@Override
protected
boolean
isLogicalConjunction
()
{
return
false
;
protected
String
getToStringInfix
()
{
return
" || "
;
}
/**
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java
浏览文件 @
4826cae0
...
...
@@ -31,6 +31,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import
org.springframework.util.AntPathMatcher
;
import
org.springframework.util.PathMatcher
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.util.UrlPathHelper
;
/**
* Test for {@link AbstractHandlerMethodMapping}.
...
...
@@ -89,10 +90,13 @@ public class HandlerMethodMappingTests {
private
static
class
MyHandlerMethodMapping
extends
AbstractHandlerMethodMapping
<
String
>
{
private
UrlPathHelper
pathHelper
=
new
UrlPathHelper
();
private
PathMatcher
pathMatcher
=
new
AntPathMatcher
();
@Override
protected
String
getMatchingMapping
(
String
pattern
,
String
lookupPath
,
HttpServletRequest
request
)
{
protected
String
getMatchingMapping
(
String
pattern
,
HttpServletRequest
request
)
{
String
lookupPath
=
pathHelper
.
getLookupPathForRequest
(
request
);
return
pathMatcher
.
match
(
pattern
,
lookupPath
)
?
pattern
:
null
;
}
...
...
@@ -103,7 +107,8 @@ public class HandlerMethodMappingTests {
}
@Override
protected
Comparator
<
String
>
getMappingComparator
(
String
lookupPath
,
HttpServletRequest
request
)
{
protected
Comparator
<
String
>
getMappingComparator
(
HttpServletRequest
request
)
{
String
lookupPath
=
pathHelper
.
getLookupPathForRequest
(
request
);
return
pathMatcher
.
getPatternComparator
(
lookupPath
);
}
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoComparatorTests.java
浏览文件 @
4826cae0
...
...
@@ -34,7 +34,6 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
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
;
/**
* Test fixture with {@link RequestMappingHandlerMapping} testing its {@link RequestMappingInfo} comparator.
...
...
@@ -57,8 +56,7 @@ public class RequestMappingInfoComparatorTests {
@Test
public
void
moreSpecificPatternWins
()
{
request
.
setRequestURI
(
"/foo"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
lookupPath
,
request
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
request
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
new
String
[]{
"/fo*"
});
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
new
String
[]{
"/foo"
});
...
...
@@ -68,8 +66,7 @@ public class RequestMappingInfoComparatorTests {
@Test
public
void
equalPatterns
()
{
request
.
setRequestURI
(
"/foo"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
lookupPath
,
request
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
request
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
new
String
[]{
"/foo*"
});
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
new
String
[]{
"/foo*"
});
...
...
@@ -79,20 +76,19 @@ public class RequestMappingInfoComparatorTests {
@Test
public
void
greaterNumberOfMatchingPatternsWins
()
throws
Exception
{
request
.
setRequestURI
(
"/foo.html"
);
String
lookupPath
=
new
UrlPathHelper
().
getLookupPathForRequest
(
request
);
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
);
RequestMappingInfo
match1
=
handlerMapping
.
getMatchingMapping
(
key1
,
request
);
RequestMappingInfo
match2
=
handlerMapping
.
getMatchingMapping
(
key2
,
request
);
List
<
RequestMappingInfo
>
matches
=
asList
(
match1
,
match2
);
Collections
.
sort
(
matches
,
handlerMapping
.
getMappingComparator
(
lookupPath
,
request
));
Collections
.
sort
(
matches
,
handlerMapping
.
getMappingComparator
(
request
));
assertSame
(
match2
.
getPatternsCondition
(),
matches
.
get
(
0
).
getPatternsCondition
());
}
@Test
public
void
oneMethodWinsOverNone
()
{
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
""
,
request
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
request
);
RequestMappingInfo
key1
=
new
RequestMappingInfo
(
null
);
RequestMappingInfo
key2
=
new
RequestMappingInfo
(
null
,
new
RequestMethod
[]
{
RequestMethod
.
GET
});
...
...
@@ -108,7 +104,7 @@ public class RequestMappingInfoComparatorTests {
new
ParamsRequestCondition
(
"foo"
),
null
,
null
,
null
);
List
<
RequestMappingInfo
>
list
=
asList
(
empty
,
oneMethod
,
oneMethodOneParam
);
Collections
.
shuffle
(
list
);
Collections
.
sort
(
list
,
handlerMapping
.
getMappingComparator
(
""
,
request
));
Collections
.
sort
(
list
,
handlerMapping
.
getMappingComparator
(
request
));
assertEquals
(
oneMethodOneParam
,
list
.
get
(
0
));
assertEquals
(
oneMethod
,
list
.
get
(
1
));
...
...
@@ -122,7 +118,7 @@ public class RequestMappingInfoComparatorTests {
RequestMappingInfo
none
=
new
RequestMappingInfo
(
null
);
request
.
addHeader
(
"Accept"
,
"application/xml, text/html"
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
""
,
request
);
Comparator
<
RequestMappingInfo
>
comparator
=
handlerMapping
.
getMappingComparator
(
request
);
int
result
=
comparator
.
compare
(
html
,
xml
);
assertTrue
(
"Invalid comparison result: "
+
result
,
result
>
0
);
...
...
@@ -134,14 +130,14 @@ public class RequestMappingInfoComparatorTests {
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"application/xml, text/*"
);
comparator
=
handlerMapping
.
getMappingComparator
(
""
,
request
);
comparator
=
handlerMapping
.
getMappingComparator
(
request
);
assertTrue
(
comparator
.
compare
(
html
,
xml
)
>
0
);
assertTrue
(
comparator
.
compare
(
xml
,
html
)
<
0
);
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"application/pdf"
);
comparator
=
handlerMapping
.
getMappingComparator
(
""
,
request
);
comparator
=
handlerMapping
.
getMappingComparator
(
request
);
assertTrue
(
comparator
.
compare
(
html
,
xml
)
==
0
);
assertTrue
(
comparator
.
compare
(
xml
,
html
)
==
0
);
...
...
@@ -149,7 +145,7 @@ public class RequestMappingInfoComparatorTests {
// See SPR-7000
request
=
new
MockHttpServletRequest
();
request
.
addHeader
(
"Accept"
,
"text/html;q=0.9,application/xml"
);
comparator
=
handlerMapping
.
getMappingComparator
(
""
,
request
);
comparator
=
handlerMapping
.
getMappingComparator
(
request
);
assertTrue
(
comparator
.
compare
(
html
,
xml
)
>
0
);
assertTrue
(
comparator
.
compare
(
xml
,
html
)
<
0
);
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoTests.java
浏览文件 @
4826cae0
...
...
@@ -87,34 +87,34 @@ public class RequestMappingInfoTests {
@Test
public
void
matchPatternsToRequest
()
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
RequestMappingInfo
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
(
request
);
RequestMappingInfo
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
match
);
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo/bar"
);
match
=
createFromPatterns
(
"/foo/*"
).
getMatchingRequestMapping
(
request
);
match
=
createFromPatterns
(
"/foo/*"
).
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
"Pattern match"
,
match
);
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo.html"
);
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
(
request
);
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
"Implicit match by extension"
,
match
);
assertEquals
(
"Contains matched pattern"
,
"/foo.*"
,
match
.
getPatternsCondition
().
getPatterns
().
iterator
().
next
());
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo/"
);
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
(
request
);
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
"Implicit match by trailing slash"
,
match
);
assertEquals
(
"Contains matched pattern"
,
"/foo/"
,
match
.
getPatternsCondition
().
getPatterns
().
iterator
().
next
());
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo.html"
);
match
=
createFromPatterns
(
"/foo.jpg"
).
getMatchingRequestMapping
(
request
);
match
=
createFromPatterns
(
"/foo.jpg"
).
getMatchingRequestMapping
Info
(
request
);
assertNull
(
"Implicit match ignored if pattern has extension"
,
match
);
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo.html"
);
match
=
createFromPatterns
(
"/foo.jpg"
).
getMatchingRequestMapping
(
request
);
match
=
createFromPatterns
(
"/foo.jpg"
).
getMatchingRequestMapping
Info
(
request
);
assertNull
(
"Implicit match ignored on pattern with trailing slash"
,
match
);
}
...
...
@@ -124,17 +124,17 @@ public class RequestMappingInfoTests {
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
RequestMappingInfo
key
=
createFromPatterns
(
"/foo"
);
RequestMappingInfo
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
(
request
);
RequestMappingInfo
match
=
createFromPatterns
(
"/foo"
).
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
"No method matches any method"
,
match
);
key
=
new
RequestMappingInfo
(
new
String
[]{
"/foo"
},
GET
);
match
=
key
.
getMatchingRequestMapping
(
request
);
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
"Exact match"
,
match
);
key
=
new
RequestMappingInfo
(
new
String
[]{
"/foo"
},
POST
);
match
=
key
.
getMatchingRequestMapping
(
request
);
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNull
(
"No match"
,
match
);
}
...
...
@@ -144,13 +144,13 @@ public class RequestMappingInfoTests {
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/foo"
);
RequestMappingInfo
key
=
new
RequestMappingInfo
(
new
String
[]
{
"/foo*"
,
"/bar"
},
GET
,
POST
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
RequestMappingInfo
expected
=
new
RequestMappingInfo
(
new
String
[]
{
"/foo*"
},
GET
);
assertEquals
(
"Matching RequestKey contains matched patterns and methods only"
,
expected
,
match
);
key
=
createFromPatterns
(
"/**"
,
"/foo*"
,
"/foo"
);
match
=
key
.
getMatchingRequestMapping
(
request
);
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
expected
=
createFromPatterns
(
"/foo"
,
"/foo*"
,
"/**"
);
assertEquals
(
"Matched patterns are sorted with best match at the top"
,
expected
,
match
);
...
...
@@ -165,14 +165,14 @@ public class RequestMappingInfoTests {
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
new
ParamsRequestCondition
(
"foo=bar"
),
null
,
null
,
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
match
);
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
new
ParamsRequestCondition
(
"foo!=bar"
),
null
,
null
,
null
);
match
=
key
.
getMatchingRequestMapping
(
request
);
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNull
(
match
);
}
...
...
@@ -186,14 +186,14 @@ public class RequestMappingInfoTests {
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
new
HeadersRequestCondition
(
"foo=bar"
),
null
,
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
match
);
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
new
HeadersRequestCondition
(
"foo!=bar"
),
null
,
null
);
match
=
key
.
getMatchingRequestMapping
(
request
);
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNull
(
match
);
}
...
...
@@ -207,14 +207,14 @@ public class RequestMappingInfoTests {
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
null
,
new
ConsumesRequestCondition
(
"text/plain"
),
null
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
match
);
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
null
,
new
ConsumesRequestCondition
(
"application/xml"
),
null
);
match
=
key
.
getMatchingRequestMapping
(
request
);
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNull
(
match
);
}
...
...
@@ -228,14 +228,14 @@ public class RequestMappingInfoTests {
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
null
,
null
,
new
ProducesRequestCondition
(
"text/plain"
));
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
(
request
);
RequestMappingInfo
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNotNull
(
match
);
key
=
new
RequestMappingInfo
(
new
PatternsRequestCondition
(
"/foo"
),
null
,
null
,
null
,
null
,
new
ProducesRequestCondition
(
"application/xml"
));
match
=
key
.
getMatchingRequestMapping
(
request
);
match
=
key
.
getMatchingRequestMapping
Info
(
request
);
assertNull
(
match
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录