Skip to content

Commit c8d6360

Browse files
author
Keith Donald
committed
ability to have multiple path patterns per mapped interceptor definition
1 parent d4a21f1 commit c8d6360

File tree

8 files changed

+92
-64
lines changed

8 files changed

+92
-64
lines changed

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,28 @@
3737
class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
3838

3939
public BeanDefinition parse(Element element, ParserContext parserContext) {
40-
List<Element> interceptors = DomUtils.getChildElementsByTagName(element, "interceptor");
40+
List<Element> interceptors = DomUtils.getChildElementsByTagName(element, new String[] { "bean", "interceptor" });
4141
for (Element interceptor : interceptors) {
4242
RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
43-
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptor.getAttribute("path"));
44-
RootBeanDefinition interceptorDef = new RootBeanDefinition(interceptor.getAttribute("class"));
45-
BeanDefinitionHolder holder = new BeanDefinitionHolder(interceptorDef, parserContext.getReaderContext().generateBeanName(interceptorDef));
46-
holder = parserContext.getDelegate().decorateBeanDefinitionIfRequired(interceptor, holder);
47-
parserContext.getDelegate().parseConstructorArgElements(interceptor, interceptorDef);
48-
parserContext.getDelegate().parsePropertyElements(interceptor, interceptorDef);
49-
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, holder);
43+
mappedInterceptorDef.setSource(parserContext.extractSource(interceptor));
44+
String[] pathPatterns;
45+
BeanDefinitionHolder interceptorDef;
46+
if ("interceptor".equals(interceptor.getLocalName())) {
47+
List<Element> paths = DomUtils.getChildElementsByTagName(interceptor, "path");
48+
pathPatterns = new String[paths.size()];
49+
for (int i = 0; i < paths.size(); i++) {
50+
pathPatterns[i] = paths.get(i).getAttribute("value");
51+
}
52+
Element interceptorBean = DomUtils.getChildElementByTagName(interceptor, "bean");
53+
interceptorDef = parserContext.getDelegate().parseBeanDefinitionElement(interceptorBean);
54+
interceptorDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(interceptorBean, interceptorDef);
55+
} else {
56+
pathPatterns = null;
57+
interceptorDef = parserContext.getDelegate().parseBeanDefinitionElement(interceptor);
58+
interceptorDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(interceptor, interceptorDef);
59+
}
60+
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, pathPatterns);
61+
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, interceptorDef);
5062
parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);
5163
}
5264
return null;

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*/
2626
public final class MappedInterceptor {
2727

28-
private final String pathPattern;
28+
private final String[] pathPatterns;
2929

3030
private final HandlerInterceptor interceptor;
3131

@@ -34,8 +34,8 @@ public final class MappedInterceptor {
3434
* @param pathPattern the path pattern
3535
* @param interceptor the interceptor
3636
*/
37-
public MappedInterceptor(String pathPattern, HandlerInterceptor interceptor) {
38-
this.pathPattern = pathPattern;
37+
public MappedInterceptor(String[] pathPatterns, HandlerInterceptor interceptor) {
38+
this.pathPatterns = pathPatterns;
3939
this.interceptor = interceptor;
4040
}
4141

@@ -44,16 +44,16 @@ public MappedInterceptor(String pathPattern, HandlerInterceptor interceptor) {
4444
* @param pathPattern the path pattern
4545
* @param interceptor the interceptor
4646
*/
47-
public MappedInterceptor(String pathPattern, WebRequestInterceptor interceptor) {
48-
this.pathPattern = pathPattern;
47+
public MappedInterceptor(String[] pathPatterns, WebRequestInterceptor interceptor) {
48+
this.pathPatterns = pathPatterns;
4949
this.interceptor = new WebRequestHandlerInterceptorAdapter(interceptor);
5050
}
5151

5252
/**
5353
* The path into the application the interceptor is mapped to.
5454
*/
55-
public String getPathPattern() {
56-
return pathPattern;
55+
public String[] getPathPatterns() {
56+
return pathPatterns;
5757
}
5858

5959
/**

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/MappedInterceptors.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.util.Set;
55

66
import org.springframework.util.PathMatcher;
7-
import org.springframework.util.StringUtils;
87
import org.springframework.web.servlet.HandlerInterceptor;
98

109
class MappedInterceptors {
@@ -26,9 +25,14 @@ public Set<HandlerInterceptor> getInterceptors(String lookupPath, PathMatcher pa
2625
}
2726

2827
private boolean matches(MappedInterceptor interceptor, String lookupPath, PathMatcher pathMatcher) {
29-
String pathPattern = interceptor.getPathPattern();
30-
if (StringUtils.hasText(pathPattern)) {
31-
return pathMatcher.match(pathPattern, lookupPath);
28+
String[] pathPatterns = interceptor.getPathPatterns();
29+
if (pathPatterns != null) {
30+
for (String pattern : pathPatterns) {
31+
if (pathMatcher.match(pattern, lookupPath)) {
32+
return true;
33+
}
34+
}
35+
return false;
3236
} else {
3337
return true;
3438
}

org.springframework.web.servlet/src/main/resources/org/springframework/web/servlet/config/spring-mvc-3.0.xsd

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -50,52 +50,54 @@
5050

5151
<xsd:element name="interceptors">
5252
<xsd:annotation>
53-
<xsd:documentation source="java:org.springframework.web.servlet.HandlerInterceptor"><![CDATA[
53+
<xsd:documentation><![CDATA[
5454
The ordered set of interceptors that intercept HTTP Servlet Requests handled by Controllers.
55-
Interceptors allow a request to be pre/post processed before/after handling.
56-
Each inteceptor should be configured as an inner bean that implements either the org.springframework.web.servlet.HandlerInterceptor or org.springframework.web.context.request.WebRequestInterceptor interface.
57-
The interceptors in this set are automatically configured on each registered HandlerMapping.
55+
Interceptors allow requests to be pre/post processed before/after handling.
56+
Each inteceptor must implement the org.springframework.web.servlet.HandlerInterceptor or org.springframework.web.context.request.WebRequestInterceptor interface.
57+
The interceptors in this set are automatically configured on each registered HandlerMapping.
58+
The URI paths each interceptor applies to are configurable.
5859
]]></xsd:documentation>
5960
</xsd:annotation>
6061
<xsd:complexType>
61-
<xsd:sequence>
62-
<xsd:element name="interceptor" maxOccurs="unbounded">
62+
<xsd:choice maxOccurs="unbounded">
63+
<xsd:element ref="beans:bean">
6364
<xsd:annotation>
6465
<xsd:documentation source="java:org.springframework.web.servlet.handler.MappedInterceptor"><![CDATA[
65-
Registers a interceptor definition.
66+
Registers an interceptor that intercepts every request regardless of its URI path.
67+
]]></xsd:documentation>
68+
</xsd:annotation>
69+
</xsd:element>
70+
<xsd:element name="interceptor">
71+
<xsd:annotation>
72+
<xsd:documentation source="java:org.springframework.web.servlet.handler.MappedInterceptor"><![CDATA[
73+
Registers an interceptor that interceptors requests sent to one or more URI paths.
6674
]]></xsd:documentation>
6775
</xsd:annotation>
6876
<xsd:complexType>
69-
<xsd:choice minOccurs="0" maxOccurs="unbounded">
70-
<xsd:element ref="beans:constructor-arg"/>
71-
<xsd:element ref="beans:property"/>
72-
</xsd:choice>
73-
<xsd:attribute name="path" type="xsd:string">
74-
<xsd:annotation>
75-
<xsd:documentation><![CDATA[
76-
The path into the application intercepted by this interceptor.
77-
Exact path mapping URIs (such as "/myPath") are supported as well as Ant-stype path patterns (such as /myPath/**).
78-
If not specified, the interceptor intercepts all paths ("/**").
79-
]]></xsd:documentation>
80-
</xsd:annotation>
81-
</xsd:attribute>
82-
<xsd:attribute name="class" type="xsd:string" use="required">
83-
<xsd:annotation>
84-
<xsd:documentation source="java:java.lang.Class"><![CDATA[
85-
The interceptor class.
86-
Must implement org.springframework.web.servlet.HandlerInterceptor or org.springframework.web.context.request.WebRequestInterceptor.
87-
]]></xsd:documentation>
88-
<xsd:appinfo>
89-
<tool:annotation kind="direct">
90-
<tool:expected-type type="java.lang.Class"/>
91-
</tool:annotation>
92-
</xsd:appinfo>
93-
</xsd:annotation>
94-
</xsd:attribute>
95-
<xsd:anyAttribute namespace="##other" processContents="lax"/>
77+
<xsd:sequence>
78+
<xsd:element name="path" maxOccurs="unbounded">
79+
<xsd:complexType>
80+
<xsd:attribute name="value" type="xsd:string" use="required">
81+
<xsd:annotation>
82+
<xsd:documentation><![CDATA[
83+
A path into the application intercepted by this interceptor.
84+
Exact path mapping URIås (such as "/myPath") are supported as well as Ant-stype path patterns (such as /myPath/**).
85+
]]></xsd:documentation>
86+
</xsd:annotation>
87+
</xsd:attribute>
88+
</xsd:complexType>
89+
</xsd:element>
90+
<xsd:element ref="beans:bean">
91+
<xsd:annotation>
92+
<xsd:documentation><![CDATA[
93+
The interceptor's bean definition.
94+
]]></xsd:documentation>
95+
</xsd:annotation>
96+
</xsd:element>
97+
</xsd:sequence>
9698
</xsd:complexType>
9799
</xsd:element>
98-
</xsd:sequence>
100+
</xsd:choice>
99101
</xsd:complexType>
100102
</xsd:element>
101103

org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.springframework.core.convert.ConversionFailedException;
3636
import org.springframework.core.convert.ConversionService;
3737
import org.springframework.core.io.ClassPathResource;
38-
import org.springframework.core.style.StylerUtils;
3938
import org.springframework.format.annotation.DateTimeFormat;
4039
import org.springframework.format.annotation.DateTimeFormat.ISO;
4140
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
@@ -49,7 +48,6 @@
4948
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
5049
import org.springframework.web.bind.annotation.RequestMapping;
5150
import org.springframework.web.bind.annotation.RequestParam;
52-
import org.springframework.web.context.request.Log4jNestedDiagnosticContextInterceptor;
5351
import org.springframework.web.context.support.GenericWebApplicationContext;
5452
import org.springframework.web.servlet.HandlerExecutionChain;
5553
import org.springframework.web.servlet.ModelAndView;
@@ -170,6 +168,11 @@ public void testInterceptors() throws Exception {
170168
assertEquals(4, chain.getInterceptors().length);
171169
assertTrue(chain.getInterceptors()[3] instanceof WebRequestHandlerInterceptorAdapter);
172170

171+
request.setRequestURI("/foo/logged");
172+
chain = mapping.getHandler(request);
173+
assertEquals(4, chain.getInterceptors().length);
174+
assertTrue(chain.getInterceptors()[3] instanceof WebRequestHandlerInterceptorAdapter);
175+
173176
}
174177

175178
@Test

org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-bean-decoration.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
<mvc:annotation-driven />
1010

1111
<mvc:interceptors>
12-
<mvc:interceptor class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang" />
13-
<mvc:interceptor class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
12+
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang" />
13+
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
1414
<property name="paramName" value="style" />
15-
</mvc:interceptor>
15+
</bean>
1616
</mvc:interceptors>
1717

1818
</beans>

org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-interceptors.xml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,16 @@
88
<mvc:annotation-driven />
99

1010
<mvc:interceptors>
11-
<mvc:interceptor class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
12-
<mvc:interceptor path="/**" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
13-
<mvc:interceptor path="/logged/**" class="org.springframework.web.context.request.Log4jNestedDiagnosticContextInterceptor" />
11+
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
12+
<mvc:interceptor>
13+
<mvc:path value="/**" />
14+
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
15+
</mvc:interceptor>
16+
<mvc:interceptor>
17+
<mvc:path value="/logged/**" />
18+
<mvc:path value="/foo/logged" />
19+
<bean class="org.springframework.web.context.request.Log4jNestedDiagnosticContextInterceptor" />
20+
</mvc:interceptor>
1421
</mvc:interceptors>
1522

1623
</beans>

org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-controllers.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
<mvc:view-controller path="/bar" view-name="baz" />
1313

1414
<mvc:interceptors>
15-
<mvc:interceptor class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
16-
<mvc:interceptor class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
15+
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
16+
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
1717
</mvc:interceptors>
1818

1919
</beans>

0 commit comments

Comments
 (0)