Support custom PathMatcher for MappedInterceptor's

Issue: SPR-11197
This commit is contained in:
Rossen Stoyanchev
2014-01-03 16:42:26 -05:00
parent abb8a93e2f
commit de280b01fe
8 changed files with 190 additions and 20 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.web.servlet.config;
import java.util.List;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -44,6 +45,11 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compDefinition);
RuntimeBeanReference pathMatcherRef = null;
if (element.hasAttribute("path-matcher")) {
pathMatcherRef = new RuntimeBeanReference(element.getAttribute("path-matcher"));
}
List<Element> interceptors = DomUtils.getChildElementsByTagName(element, "bean", "ref", "interceptor");
for (Element interceptor : interceptors) {
RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
@@ -66,6 +72,10 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, interceptorBean);
if (pathMatcherRef != null) {
mappedInterceptorDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
}
String beanName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);
parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, beanName));
}

View File

@@ -16,12 +16,11 @@
package org.springframework.web.servlet.config.annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.MappedInterceptor;
@@ -40,6 +39,9 @@ public class InterceptorRegistration {
private final List<String> excludePatterns = new ArrayList<String>();
private PathMatcher pathMatcher;
/**
* Creates an {@link InterceptorRegistration} instance.
*/
@@ -64,6 +66,17 @@ public class InterceptorRegistration {
return this;
}
/**
* A PathMatcher implementation to use with this interceptor. This is an optional,
* advanced property required only if using custom PathMatcher implementations
* that support mapping metadata other than the Ant path patterns supported
* by default.
*/
public InterceptorRegistration pathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
return this;
}
/**
* Returns the underlying interceptor. If URL patterns are provided the returned type is
* {@link MappedInterceptor}; otherwise {@link HandlerInterceptor}.
@@ -72,7 +85,12 @@ public class InterceptorRegistration {
if (this.includePatterns.isEmpty()) {
return this.interceptor;
}
return new MappedInterceptor(toArray(this.includePatterns), toArray(this.excludePatterns), interceptor);
MappedInterceptor mappedInterceptor = new MappedInterceptor(
toArray(this.includePatterns), toArray(this.excludePatterns), interceptor);
if (this.pathMatcher != null) {
mappedInterceptor.setPathMatcher(this.pathMatcher);
}
return mappedInterceptor;
}
private static String[] toArray(List<String> list) {

View File

@@ -36,6 +36,8 @@ public final class MappedInterceptor {
private final HandlerInterceptor interceptor;
private PathMatcher pathMatcher;
/**
* Create a new MappedInterceptor instance.
@@ -58,6 +60,7 @@ public final class MappedInterceptor {
this.interceptor = interceptor;
}
/**
* Create a new MappedInterceptor instance.
* @param includePatterns the path patterns to map with a {@code null} value matching to all paths
@@ -77,6 +80,26 @@ public final class MappedInterceptor {
}
/**
* Configure a PathMatcher to use with this MappedInterceptor instead of the
* one passed by default to the {@link #matches(String, org.springframework.util.PathMatcher)}
* method. This is an advanced property that is only required when using custom
* PathMatcher implementations that support mapping metadata other than the
* Ant-style path patterns supported by default.
*
* @param pathMatcher the path matcher to use
*/
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
/**
* The configured PathMatcher, or {@code null}.
*/
public PathMatcher getPathMatcher() {
return this.pathMatcher;
}
/**
* The path into the application the interceptor is mapped to.
*/
@@ -97,9 +120,10 @@ public final class MappedInterceptor {
* @param pathMatcher a path matcher for path pattern matching
*/
public boolean matches(String lookupPath, PathMatcher pathMatcher) {
PathMatcher pathMatcherToUse = (this.pathMatcher != null) ? this.pathMatcher : pathMatcher;
if (this.excludePatterns != null) {
for (String pattern : this.excludePatterns) {
if (pathMatcher.match(pattern, lookupPath)) {
if (pathMatcherToUse.match(pattern, lookupPath)) {
return false;
}
}
@@ -109,7 +133,7 @@ public final class MappedInterceptor {
}
else {
for (String pattern : this.includePatterns) {
if (pathMatcher.match(pattern, lookupPath)) {
if (pathMatcherToUse.match(pattern, lookupPath)) {
return true;
}
}