Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
9779ca19
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,发现更多精彩内容 >>
提交
9779ca19
编写于
2月 22, 2011
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SPR-7976 Add MvcInterceptors features.
上级
5a5fff52
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
371 addition
and
32 deletion
+371
-32
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java
.../web/servlet/config/InterceptorsBeanDefinitionParser.java
+27
-32
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptors.java
...g/springframework/web/servlet/config/MvcInterceptors.java
+158
-0
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptorsExecutor.java
...framework/web/servlet/config/MvcInterceptorsExecutor.java
+60
-0
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcInterceptorsTests.java
...ingframework/web/servlet/config/MvcInterceptorsTests.java
+126
-0
未找到文件。
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java
浏览文件 @
9779ca19
...
...
@@ -18,59 +18,54 @@ package org.springframework.web.servlet.config;
import
java.util.List
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.BeanDefinitionHolder
;
import
org.springframework.beans.factory.parsing.BeanComponentDefinition
;
import
org.springframework.beans.factory.parsing.CompositeComponentDefinition
;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
import
org.springframework.beans.factory.xml.BeanDefinitionParser
;
import
org.springframework.beans.factory.xml.ParserContext
;
import
org.springframework.context.config.AbstractSpecificationBeanDefinitionParser
;
import
org.springframework.context.config.FeatureSpecification
;
import
org.springframework.util.xml.DomUtils
;
import
org.springframework.web.servlet.handler.MappedInterceptor
;
import
org.w3c.dom.Element
;
/**
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses a {@code interceptors} element to register
* a set of {@link MappedInterceptor} definitions.
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses
* a {@code interceptors} element to register set of {@link MappedInterceptor}
* definitions.
*
* @author Keith Donald
* @author Rossen Stoyanchev
*
* @since 3.0
*/
class
InterceptorsBeanDefinitionParser
implements
BeanDefinitionParser
{
class
InterceptorsBeanDefinitionParser
extends
AbstractSpecificationBeanDefinitionParser
{
/**
* Parses the {@code <mvc:interceptors/>} tag.
*/
public
FeatureSpecification
doParse
(
Element
element
,
ParserContext
parserContext
)
{
MvcInterceptors
mvcInterceptors
=
new
MvcInterceptors
();
public
BeanDefinition
parse
(
Element
element
,
ParserContext
parserContext
)
{
CompositeComponentDefinition
compDefinition
=
new
CompositeComponentDefinition
(
element
.
getTagName
(),
parserContext
.
extractSource
(
element
));
parserContext
.
pushContainingComponent
(
compDefinition
);
List
<
Element
>
interceptors
=
DomUtils
.
getChildElementsByTagName
(
element
,
new
String
[]
{
"bean"
,
"interceptor"
});
for
(
Element
interceptor
:
interceptors
)
{
RootBeanDefinition
mappedInterceptorDef
=
new
RootBeanDefinition
(
MappedInterceptor
.
class
);
mappedInterceptorDef
.
setSource
(
parserContext
.
extractSource
(
interceptor
));
mappedInterceptorDef
.
setRole
(
BeanDefinition
.
ROLE_INFRASTRUCTURE
);
String
[]
pathPatterns
;
BeanDefinitionHolder
interceptorDef
;
if
(
"interceptor"
.
equals
(
interceptor
.
getLocalName
()))
{
List
<
Element
>
paths
=
DomUtils
.
getChildElementsByTagName
(
interceptor
,
"mapping"
);
pathPatterns
=
new
String
[
paths
.
size
()];
String
[]
pathPatterns
=
new
String
[
paths
.
size
()];
for
(
int
i
=
0
;
i
<
paths
.
size
();
i
++)
{
pathPatterns
[
i
]
=
paths
.
get
(
i
).
getAttribute
(
"path"
);
}
Element
interceptorBean
=
DomUtils
.
getChildElementByTagName
(
interceptor
,
"bean"
);
interceptorDef
=
parserContext
.
getDelegate
().
parseBeanDefinitionElement
(
interceptorBean
);
interceptorDef
=
parserContext
.
getDelegate
().
decorateBeanDefinitionIfRequired
(
interceptorBean
,
interceptorDef
);
Element
beanElement
=
DomUtils
.
getChildElementByTagName
(
interceptor
,
"bean"
);
mvcInterceptors
.
interceptor
(
pathPatterns
,
parseBeanElement
(
parserContext
,
beanElement
));
}
else
{
pathPatterns
=
null
;
interceptorDef
=
parserContext
.
getDelegate
().
parseBeanDefinitionElement
(
interceptor
);
interceptorDef
=
parserContext
.
getDelegate
().
decorateBeanDefinitionIfRequired
(
interceptor
,
interceptorDef
);
mvcInterceptors
.
interceptor
(
null
,
parseBeanElement
(
parserContext
,
interceptor
));
}
mappedInterceptorDef
.
getConstructorArgumentValues
().
addIndexedArgumentValue
(
0
,
pathPatterns
);
mappedInterceptorDef
.
getConstructorArgumentValues
().
addIndexedArgumentValue
(
1
,
interceptorDef
);
String
mappedInterceptorName
=
parserContext
.
getReaderContext
().
registerWithGeneratedName
(
mappedInterceptorDef
);
parserContext
.
registerComponent
(
new
BeanComponentDefinition
(
mappedInterceptorDef
,
mappedInterceptorName
));
}
parserContext
.
popAndRegisterContainingComponent
();
return
null
;
return
mvcInterceptors
;
}
private
BeanDefinitionHolder
parseBeanElement
(
ParserContext
parserContext
,
Element
interceptor
)
{
BeanDefinitionHolder
beanDef
=
parserContext
.
getDelegate
().
parseBeanDefinitionElement
(
interceptor
);
beanDef
=
parserContext
.
getDelegate
().
decorateBeanDefinitionIfRequired
(
interceptor
,
beanDef
);
return
beanDef
;
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptors.java
0 → 100644
浏览文件 @
9779ca19
/*
* 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.config
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
import
org.springframework.beans.factory.config.BeanDefinitionHolder
;
import
org.springframework.beans.factory.parsing.ProblemCollector
;
import
org.springframework.context.config.AbstractFeatureSpecification
;
import
org.springframework.context.config.FeatureSpecificationExecutor
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.context.request.WebRequestInterceptor
;
import
org.springframework.web.servlet.HandlerInterceptor
;
import
org.springframework.web.servlet.handler.MappedInterceptor
;
/**
* Specifies the Spring MVC "interceptors" container feature. The feature
* registers one or more {@link MappedInterceptor} bean definitions. A
* MappedInterceptor encapsulates an interceptor and one or more (optional)
* path patterns to which the interceptor is mapped. The interceptor can be
* of type {@link HandlerInterceptor} or {@link WebRequestInterceptor}.
* An interceptor can also be provided without path patterns in which case
* it applies globally to all handler invocations.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
MvcInterceptors
extends
AbstractFeatureSpecification
{
private
static
final
Class
<?
extends
FeatureSpecificationExecutor
>
EXECUTOR_TYPE
=
MvcInterceptorsExecutor
.
class
;
private
Map
<
Object
,
String
[]>
interceptorMappings
=
new
LinkedHashMap
<
Object
,
String
[]>();
/**
* Creates an MvcInterceptors instance.
*/
public
MvcInterceptors
()
{
super
(
EXECUTOR_TYPE
);
}
/**
* Add one or more {@link HandlerInterceptor HandlerInterceptors} that should
* intercept all handler invocations.
*
* @param interceptors one or more interceptors
*/
public
MvcInterceptors
globalInterceptors
(
HandlerInterceptor
...
interceptors
)
{
addInterceptorMappings
(
null
,
interceptors
);
return
this
;
}
/**
* Add one or more {@link WebRequestInterceptor WebRequestInterceptors} that should
* intercept all handler invocations.
*
* @param interceptors one or more interceptors
*/
public
MvcInterceptors
globalInterceptors
(
WebRequestInterceptor
...
interceptors
)
{
addInterceptorMappings
(
null
,
interceptors
);
return
this
;
}
/**
* Add one or more interceptors by bean name that should intercept all handler
* invocations.
*
* @param interceptors interceptor bean names
*/
public
MvcInterceptors
globalInterceptors
(
String
...
interceptors
)
{
addInterceptorMappings
(
null
,
interceptors
);
return
this
;
}
/**
* Add one or more {@link HandlerInterceptor HandlerInterceptors} and map
* them to the specified path patterns.
*
* @param pathPatterns the pathPatterns to map the interceptor to
* @param interceptors the interceptors
*/
public
MvcInterceptors
mappedInterceptors
(
String
[]
pathPatterns
,
HandlerInterceptor
...
interceptors
)
{
addInterceptorMappings
(
pathPatterns
,
interceptors
);
return
this
;
}
/**
* Add one or more {@link WebRequestInterceptor WebRequestInterceptors} and
* map them to the specified path patterns.
*
* @param pathPatterns the pathPatterns to map the interceptor to
* @param interceptors the interceptors
*/
public
MvcInterceptors
mappedInterceptors
(
String
[]
pathPatterns
,
WebRequestInterceptor
...
interceptors
)
{
addInterceptorMappings
(
pathPatterns
,
interceptors
);
return
this
;
}
/**
* Add one or more interceptors by bean name and map them to the specified
* path patterns.
*
* @param pathPatterns the pathPatterns to map to
* @param interceptors the interceptors
*/
public
MvcInterceptors
mappedInterceptors
(
String
[]
pathPatterns
,
String
...
interceptors
)
{
addInterceptorMappings
(
pathPatterns
,
interceptors
);
return
this
;
}
void
interceptor
(
String
[]
pathPatterns
,
BeanDefinitionHolder
interceptor
)
{
addInterceptorMappings
(
pathPatterns
,
new
Object
[]
{
interceptor
});
}
Map
<
Object
,
String
[]>
interceptorMappings
()
{
return
Collections
.
unmodifiableMap
(
interceptorMappings
);
}
private
void
addInterceptorMappings
(
String
[]
pathPatterns
,
Object
[]
interceptors
)
{
for
(
Object
interceptor
:
interceptors
)
{
interceptorMappings
.
put
(
interceptor
,
pathPatterns
);
}
}
@Override
protected
void
doValidate
(
ProblemCollector
problems
)
{
if
(
interceptorMappings
.
size
()
==
0
)
{
problems
.
error
(
"No interceptors defined."
);
}
for
(
Object
interceptor
:
interceptorMappings
.
keySet
())
{
if
(
interceptor
==
null
)
{
problems
.
error
(
"Null interceptor provided."
);
}
if
(
interceptorMappings
.
get
(
interceptor
)
!=
null
)
{
for
(
String
pattern
:
interceptorMappings
.
get
(
interceptor
))
{
if
(!
StringUtils
.
hasText
(
pattern
))
{
problems
.
error
(
"Empty path pattern specified for "
+
interceptor
);
}
}
}
}
}
}
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcInterceptorsExecutor.java
0 → 100644
浏览文件 @
9779ca19
/*
* 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.config
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.parsing.BeanComponentDefinition
;
import
org.springframework.beans.factory.parsing.ComponentRegistrar
;
import
org.springframework.beans.factory.parsing.CompositeComponentDefinition
;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
import
org.springframework.context.config.AbstractSpecificationExecutor
;
import
org.springframework.context.config.SpecificationContext
;
import
org.springframework.web.servlet.handler.MappedInterceptor
;
/**
* Executes {@link MvcInterceptors} specification, creating and registering
* bean definitions as appropriate based on the configuration within.
*
* @author Keith Donald
* @author Rossen Stoyanchev
*
* @since 3.1
*/
final
class
MvcInterceptorsExecutor
extends
AbstractSpecificationExecutor
<
MvcInterceptors
>
{
@Override
protected
void
doExecute
(
MvcInterceptors
spec
,
SpecificationContext
specContext
)
{
ComponentRegistrar
registrar
=
specContext
.
getRegistrar
();
Object
source
=
spec
.
source
();
CompositeComponentDefinition
compDefinition
=
new
CompositeComponentDefinition
(
spec
.
sourceName
(),
source
);
for
(
Object
interceptor
:
spec
.
interceptorMappings
().
keySet
())
{
RootBeanDefinition
beanDef
=
new
RootBeanDefinition
(
MappedInterceptor
.
class
);
beanDef
.
setSource
(
source
);
beanDef
.
setRole
(
BeanDefinition
.
ROLE_INFRASTRUCTURE
);
beanDef
.
getConstructorArgumentValues
().
addIndexedArgumentValue
(
0
,
spec
.
interceptorMappings
().
get
(
interceptor
));
beanDef
.
getConstructorArgumentValues
().
addIndexedArgumentValue
(
1
,
interceptor
);
String
beanName
=
registrar
.
registerWithGeneratedName
(
beanDef
);
compDefinition
.
addNestedComponent
(
new
BeanComponentDefinition
(
beanDef
,
beanName
));
}
registrar
.
registerComponent
(
compDefinition
);
}
}
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcInterceptorsTests.java
0 → 100644
浏览文件 @
9779ca19
/*
* 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.config
;
import
static
org
.
easymock
.
EasyMock
.
capture
;
import
static
org
.
easymock
.
EasyMock
.
createMock
;
import
static
org
.
easymock
.
EasyMock
.
replay
;
import
static
org
.
junit
.
Assert
.
assertArrayEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.util.Iterator
;
import
org.easymock.Capture
;
import
org.junit.Test
;
import
org.springframework.beans.factory.parsing.Problem
;
import
org.springframework.beans.factory.parsing.ProblemReporter
;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext
;
import
org.springframework.context.annotation.Feature
;
import
org.springframework.context.annotation.FeatureConfiguration
;
import
org.springframework.web.servlet.HandlerInterceptor
;
import
org.springframework.web.servlet.handler.MappedInterceptor
;
import
org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor
;
import
org.springframework.web.servlet.i18n.LocaleChangeInterceptor
;
import
org.springframework.web.servlet.theme.ThemeChangeInterceptor
;
/**
* Test fixture for {@link MvcInterceptors}.
* @author Rossen Stoyanchev
*/
public
class
MvcInterceptorsTests
{
@Test
public
void
testInterceptors
()
{
AnnotationConfigApplicationContext
ctx
=
new
AnnotationConfigApplicationContext
();
ctx
.
register
(
MvcInterceptorsFeature
.
class
);
ctx
.
refresh
();
Iterator
<
MappedInterceptor
>
itr
=
ctx
.
getBeansOfType
(
MappedInterceptor
.
class
).
values
().
iterator
();
MappedInterceptor
interceptor
=
itr
.
next
();
assertTrue
(
interceptor
.
getInterceptor
()
instanceof
UserRoleAuthorizationInterceptor
);
assertNull
(
interceptor
.
getPathPatterns
());
interceptor
=
itr
.
next
();
assertTrue
(
interceptor
.
getInterceptor
()
instanceof
LocaleChangeInterceptor
);
assertArrayEquals
(
new
String
[]
{
"/locale"
,
"/locale/**"
},
interceptor
.
getPathPatterns
());
interceptor
=
itr
.
next
();
assertTrue
(
interceptor
.
getInterceptor
()
instanceof
ThemeChangeInterceptor
);
assertArrayEquals
(
new
String
[]
{
"/theme"
,
"/theme/**"
},
interceptor
.
getPathPatterns
());
}
@Test
public
void
validateNoInterceptors
()
{
ProblemReporter
reporter
=
createMock
(
ProblemReporter
.
class
);
Capture
<
Problem
>
captured
=
new
Capture
<
Problem
>();
reporter
.
error
(
capture
(
captured
));
replay
(
reporter
);
boolean
result
=
new
MvcInterceptors
().
validate
(
reporter
);
assertFalse
(
result
);
assertEquals
(
"No interceptors defined."
,
captured
.
getValue
().
getMessage
());
}
@Test
public
void
validateNullHandler
()
{
ProblemReporter
reporter
=
createMock
(
ProblemReporter
.
class
);
Capture
<
Problem
>
captured
=
new
Capture
<
Problem
>();
reporter
.
error
(
capture
(
captured
));
replay
(
reporter
);
HandlerInterceptor
[]
interceptors
=
new
HandlerInterceptor
[]
{
null
};
boolean
result
=
new
MvcInterceptors
().
globalInterceptors
(
interceptors
).
validate
(
reporter
);
assertFalse
(
result
);
assertTrue
(
captured
.
getValue
().
getMessage
().
contains
(
"Null interceptor"
));
}
@Test
public
void
validateEmptyPath
()
{
ProblemReporter
reporter
=
createMock
(
ProblemReporter
.
class
);
Capture
<
Problem
>
captured
=
new
Capture
<
Problem
>();
reporter
.
error
(
capture
(
captured
));
replay
(
reporter
);
HandlerInterceptor
[]
interceptors
=
new
HandlerInterceptor
[]
{
new
LocaleChangeInterceptor
()
};
String
[]
patterns
=
new
String
[]
{
""
};
boolean
result
=
new
MvcInterceptors
().
mappedInterceptors
(
patterns
,
interceptors
).
validate
(
reporter
);
assertFalse
(
result
);
assertTrue
(
captured
.
getValue
().
getMessage
().
startsWith
(
"Empty path pattern specified for "
));
}
@FeatureConfiguration
private
static
class
MvcInterceptorsFeature
{
@SuppressWarnings
(
"unused"
)
@Feature
public
MvcInterceptors
interceptors
()
{
return
new
MvcInterceptors
()
.
globalInterceptors
(
new
UserRoleAuthorizationInterceptor
())
.
mappedInterceptors
(
new
String
[]
{
"/locale"
,
"/locale/**"
},
new
LocaleChangeInterceptor
())
.
mappedInterceptors
(
new
String
[]
{
"/theme"
,
"/theme/**"
},
new
ThemeChangeInterceptor
());
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录