Reduce API Surface in PathPatternRegistry
This commit reduces the exposition of `PathPattern` instances throughout the `HandlerMapping` API and removes some methods from its public API. Issue: SPR-14544
This commit is contained in:
parent
4999898617
commit
8d43f45515
|
|
@ -18,6 +18,7 @@ package org.springframework.web.cors.reactive;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
|
||||
|
|
@ -71,12 +72,14 @@ public class UrlBasedCorsConfigurationSource implements CorsConfigurationSource
|
|||
/**
|
||||
* Set CORS configuration based on URL patterns.
|
||||
*/
|
||||
public void setCorsConfigurations(Map<PathPattern, CorsConfiguration> corsConfigurations) {
|
||||
public void setCorsConfigurations(Map<String, CorsConfiguration> corsConfigurations) {
|
||||
this.patternRegistry.clear();
|
||||
this.corsConfigurations.clear();
|
||||
if (corsConfigurations != null) {
|
||||
this.patternRegistry.addAll(corsConfigurations.keySet());
|
||||
this.corsConfigurations.putAll(corsConfigurations);
|
||||
corsConfigurations.forEach((pattern, config) -> {
|
||||
List<PathPattern> registered = this.patternRegistry.register(pattern);
|
||||
registered.forEach(p -> this.corsConfigurations.put(p, config));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.web.util.patterns;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -63,6 +62,11 @@ public class PathPatternRegistry {
|
|||
this.patterns = new HashSet<>();
|
||||
}
|
||||
|
||||
public PathPatternRegistry(Set<PathPattern> patterns) {
|
||||
this();
|
||||
this.patterns.addAll(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to match to paths irrespective of the presence of a trailing slash.
|
||||
*/
|
||||
|
|
@ -150,30 +154,6 @@ public class PathPatternRegistry {
|
|||
return this.pathPatternParser.parse(pathPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link PathPattern} instance to this registry
|
||||
* @return true if this registry did not already contain the specified {@code PathPattern}
|
||||
*/
|
||||
public boolean add(PathPattern pathPattern) {
|
||||
return this.patterns.add(pathPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all {@link PathPattern}s instance to this registry
|
||||
* @return true if this registry did not already contain at least one of the given {@code PathPattern}s
|
||||
*/
|
||||
public boolean addAll(Collection<PathPattern> pathPatterns) {
|
||||
return this.patterns.addAll(pathPatterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given {@link PathPattern} from this registry
|
||||
* @return true if this registry contained the given {@code PathPattern}
|
||||
*/
|
||||
public boolean remove(PathPattern pathPattern) {
|
||||
return this.patterns.remove(pathPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all {@link PathPattern}s from this registry
|
||||
*/
|
||||
|
|
@ -197,25 +177,7 @@ public class PathPatternRegistry {
|
|||
* @return the list of {@link PathPattern} that were registered as a result
|
||||
*/
|
||||
public List<PathPattern> register(String rawPattern) {
|
||||
String fixedPattern = prependLeadingSlash(rawPattern);
|
||||
List<PathPattern> newPatterns = new ArrayList<>();
|
||||
PathPattern pattern = this.pathPatternParser.parse(fixedPattern);
|
||||
newPatterns.add(pattern);
|
||||
if (StringUtils.hasLength(fixedPattern) && !pattern.isCatchAll()) {
|
||||
if (this.useSuffixPatternMatch) {
|
||||
if (this.fileExtensions != null && !this.fileExtensions.isEmpty()) {
|
||||
for (String extension : this.fileExtensions) {
|
||||
newPatterns.add(this.pathPatternParser.parse(fixedPattern + extension));
|
||||
}
|
||||
}
|
||||
else {
|
||||
newPatterns.add(this.pathPatternParser.parse(fixedPattern + ".*"));
|
||||
}
|
||||
}
|
||||
if (this.useTrailingSlashMatch && !fixedPattern.endsWith("/")) {
|
||||
newPatterns.add(this.pathPatternParser.parse(fixedPattern + "/"));
|
||||
}
|
||||
}
|
||||
List<PathPattern> newPatterns = generatePathPatterns(rawPattern);
|
||||
this.patterns.addAll(newPatterns);
|
||||
return newPatterns;
|
||||
}
|
||||
|
|
@ -229,6 +191,44 @@ public class PathPatternRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
private List<PathPattern> generatePathPatterns(String rawPattern) {
|
||||
String fixedPattern = prependLeadingSlash(rawPattern);
|
||||
List<PathPattern> patterns = new ArrayList<>();
|
||||
PathPattern pattern = this.pathPatternParser.parse(fixedPattern);
|
||||
patterns.add(pattern);
|
||||
if (StringUtils.hasLength(fixedPattern) && !pattern.isCatchAll()) {
|
||||
if (this.useSuffixPatternMatch) {
|
||||
if (this.fileExtensions != null && !this.fileExtensions.isEmpty()) {
|
||||
for (String extension : this.fileExtensions) {
|
||||
patterns.add(this.pathPatternParser.parse(fixedPattern + extension));
|
||||
}
|
||||
}
|
||||
else {
|
||||
patterns.add(this.pathPatternParser.parse(fixedPattern + ".*"));
|
||||
}
|
||||
}
|
||||
if (this.useTrailingSlashMatch && !fixedPattern.endsWith("/")) {
|
||||
patterns.add(this.pathPatternParser.parse(fixedPattern + "/"));
|
||||
}
|
||||
}
|
||||
return patterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given {@code rawPattern} and removes it to this registry,
|
||||
* as well as pattern variants, depending on the given options and
|
||||
* the nature of the input pattern.
|
||||
*
|
||||
* @param rawPattern raw path pattern to parse and unregister
|
||||
* @return the list of {@link PathPattern} that were unregistered as a result
|
||||
*/
|
||||
public List<PathPattern> unregister(String rawPattern) {
|
||||
List<PathPattern> unregisteredPatterns = generatePathPatterns(rawPattern);
|
||||
this.patterns.removeAll(unregisteredPatterns);
|
||||
return unregisteredPatterns;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Combine the patterns contained in the current registry
|
||||
* with the ones in the other, into a new {@code PathPatternRegistry} instance.
|
||||
|
|
|
|||
|
|
@ -146,8 +146,8 @@ public class PathPatternRegistryTests {
|
|||
PathPattern fooTwo = this.registry.parsePattern("/f?o");
|
||||
assertThat(fooOne.compareTo(fooTwo), is(0));
|
||||
|
||||
this.registry.add(fooOne);
|
||||
this.registry.add(fooTwo);
|
||||
this.registry.register("/fo?");
|
||||
this.registry.register("/f?o");
|
||||
Set<PathPattern> matches = this.registry.findMatches("/foo");
|
||||
assertThat(getPatternList(matches), Matchers.contains("/f?o", "/fo?"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,12 +84,16 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
|
|||
* from the Spring {@code ApplicationContext}. However if this property is
|
||||
* used, the auto-detection is turned off.
|
||||
*/
|
||||
public void setHandlerMap(Map<PathPattern, ResourceWebHandler> handlerMap) {
|
||||
public void setHandlerMap(Map<String, ResourceWebHandler> handlerMap) {
|
||||
if (handlerMap != null) {
|
||||
this.patternRegistry.clear();
|
||||
this.patternRegistry.addAll(handlerMap.keySet());
|
||||
this.handlerMap.clear();
|
||||
this.handlerMap.putAll(handlerMap);
|
||||
|
||||
handlerMap.forEach((pattern, handler) -> {
|
||||
this.patternRegistry
|
||||
.register(pattern)
|
||||
.forEach(pathPattern -> this.handlerMap.put(pathPattern, handler));
|
||||
});
|
||||
this.autodetect = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -143,7 +147,7 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
|
|||
"locations=" + resourceHandler.getLocations() + ", " +
|
||||
"resolvers=" + resourceHandler.getResourceResolvers());
|
||||
}
|
||||
this.patternRegistry.add(pattern);
|
||||
this.patternRegistry.register(pattern.getPatternString());
|
||||
this.handlerMap.put(pattern, resourceHandler);
|
||||
}
|
||||
}
|
||||
|
|
@ -179,11 +183,11 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
|
|||
private int getEndPathIndex(String lookupPath) {
|
||||
int suffixIndex = lookupPath.length();
|
||||
int queryIndex = lookupPath.indexOf("?");
|
||||
if(queryIndex > 0) {
|
||||
if (queryIndex > 0) {
|
||||
suffixIndex = queryIndex;
|
||||
}
|
||||
int hashIndex = lookupPath.indexOf("#");
|
||||
if(hashIndex > 0) {
|
||||
if (hashIndex > 0) {
|
||||
suffixIndex = Math.min(suffixIndex, hashIndex);
|
||||
}
|
||||
return suffixIndex;
|
||||
|
|
|
|||
|
|
@ -133,8 +133,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
|||
SortedSet<PathPattern> matches = getMatchingPatterns(lookupPath);
|
||||
|
||||
if(!matches.isEmpty()) {
|
||||
PathPatternRegistry registry = new PathPatternRegistry();
|
||||
registry.addAll(matches);
|
||||
PathPatternRegistry registry = new PathPatternRegistry(matches);
|
||||
return new PatternsRequestCondition(registry, this.pathHelper);
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
|||
private final MultiValueMap<PathPattern, T> mappingLookup = new LinkedMultiValueMap<>();
|
||||
|
||||
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
|
||||
|
||||
|
||||
private final MappingRegistry mappingRegistry = new MappingRegistry();
|
||||
|
||||
|
||||
|
|
@ -129,10 +129,10 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
|||
public void registerMapping(T mapping, Object handler, Method method) {
|
||||
this.readWriteLock.writeLock().lock();
|
||||
try {
|
||||
Set<PathPattern> patterns = getMappingPathPatterns(mapping);
|
||||
getPatternRegistry().addAll(patterns);
|
||||
patterns.forEach(pathPattern -> {
|
||||
this.mappingLookup.add(pathPattern, mapping);
|
||||
getMappingPathPatterns(mapping).forEach(pattern -> {
|
||||
getPatternRegistry().register(pattern).forEach(
|
||||
pathPattern -> this.mappingLookup.add(pathPattern, mapping)
|
||||
);
|
||||
});
|
||||
this.mappingRegistry.register(mapping, handler, method);
|
||||
}
|
||||
|
|
@ -149,8 +149,11 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
|||
public void unregisterMapping(T mapping) {
|
||||
this.readWriteLock.writeLock().lock();
|
||||
try {
|
||||
getMappingPathPatterns(mapping)
|
||||
.forEach(pathPattern -> getPatternRegistry().remove(pathPattern));
|
||||
getMappingPathPatterns(mapping).forEach(pattern -> {
|
||||
getPatternRegistry().unregister(pattern).forEach(
|
||||
pathPattern -> this.mappingLookup.remove(pathPattern, mapping)
|
||||
);
|
||||
});
|
||||
this.mappingRegistry.unregister(mapping);
|
||||
}
|
||||
finally {
|
||||
|
|
@ -420,7 +423,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
|||
/**
|
||||
* Extract and return the URL paths contained in a mapping.
|
||||
*/
|
||||
protected abstract Set<PathPattern> getMappingPathPatterns(T mapping);
|
||||
protected abstract Set<String> getMappingPathPatterns(T mapping);
|
||||
|
||||
/**
|
||||
* Check if a mapping matches the current request and return a (potentially
|
||||
|
|
|
|||
|
|
@ -74,8 +74,10 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
|||
* Get the URL path patterns associated with this {@link RequestMappingInfo}.
|
||||
*/
|
||||
@Override
|
||||
protected Set<PathPattern> getMappingPathPatterns(RequestMappingInfo info) {
|
||||
return info.getPatternsCondition().getPatterns();
|
||||
protected Set<String> getMappingPathPatterns(RequestMappingInfo info) {
|
||||
return info.getPatternsCondition().getPatterns().stream()
|
||||
.map(p -> p.getPatternString())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse
|
|||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
import org.springframework.web.util.patterns.PathPatternParser;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
|
@ -58,8 +57,7 @@ public class AppCacheManifestTransformerTests {
|
|||
ClassPathResource allowedLocation = new ClassPathResource("test/", getClass());
|
||||
ResourceWebHandler resourceHandler = new ResourceWebHandler();
|
||||
ResourceUrlProvider resourceUrlProvider = new ResourceUrlProvider();
|
||||
PathPatternParser parser = new PathPatternParser();
|
||||
resourceUrlProvider.setHandlerMap(Collections.singletonMap(parser.parse("/static/**"), resourceHandler));
|
||||
resourceUrlProvider.setHandlerMap(Collections.singletonMap("/static/**", resourceHandler));
|
||||
|
||||
VersionResourceResolver versionResolver = new VersionResourceResolver();
|
||||
versionResolver.setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy()));
|
||||
|
|
|
|||
|
|
@ -59,8 +59,7 @@ public class CssLinkResourceTransformerTests {
|
|||
ResourceWebHandler resourceHandler = new ResourceWebHandler();
|
||||
|
||||
ResourceUrlProvider resourceUrlProvider = new ResourceUrlProvider();
|
||||
PathPatternParser parser = new PathPatternParser();
|
||||
resourceUrlProvider.setHandlerMap(Collections.singletonMap(parser.parse("/static/**"), resourceHandler));
|
||||
resourceUrlProvider.setHandlerMap(Collections.singletonMap("/static/**", resourceHandler));
|
||||
|
||||
VersionResourceResolver versionResolver = new VersionResourceResolver();
|
||||
versionResolver.setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy()));
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
|||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
import org.springframework.web.util.patterns.PathPatternParser;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
|
@ -70,8 +69,7 @@ public class ResourceTransformerSupportTests {
|
|||
handler.setLocations(Collections.singletonList(new ClassPathResource("test/", getClass())));
|
||||
handler.setResourceResolvers(resolvers);
|
||||
ResourceUrlProvider urlProvider = new ResourceUrlProvider();
|
||||
PathPatternParser parser = new PathPatternParser();
|
||||
urlProvider.setHandlerMap(Collections.singletonMap(parser.parse("/resources/**"), handler));
|
||||
urlProvider.setHandlerMap(Collections.singletonMap("/resources/**", handler));
|
||||
return urlProvider;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,9 +36,6 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
|
|||
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
import org.springframework.web.server.session.DefaultWebSessionManager;
|
||||
import org.springframework.web.server.session.WebSessionManager;
|
||||
import org.springframework.web.util.patterns.PathPattern;
|
||||
import org.springframework.web.util.patterns.PathPatternParser;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
|
@ -57,7 +54,7 @@ public class ResourceUrlProviderTests {
|
|||
|
||||
private final ResourceWebHandler handler = new ResourceWebHandler();
|
||||
|
||||
private final Map<PathPattern, ResourceWebHandler> handlerMap = new HashMap<>();
|
||||
private final Map<String, ResourceWebHandler> handlerMap = new HashMap<>();
|
||||
|
||||
private final ResourceUrlProvider urlProvider = new ResourceUrlProvider();
|
||||
|
||||
|
|
@ -68,8 +65,7 @@ public class ResourceUrlProviderTests {
|
|||
this.locations.add(new ClassPathResource("testalternatepath/", getClass()));
|
||||
this.handler.setLocations(locations);
|
||||
this.handler.afterPropertiesSet();
|
||||
PathPattern staticResources = new PathPatternParser().parse("/resources/**");
|
||||
this.handlerMap.put(staticResources, this.handler);
|
||||
this.handlerMap.put("/resources/**", this.handler);
|
||||
this.urlProvider.setHandlerMap(this.handlerMap);
|
||||
}
|
||||
|
||||
|
|
@ -125,8 +121,7 @@ public class ResourceUrlProviderTests {
|
|||
resolvers.add(new PathResourceResolver());
|
||||
otherHandler.setResourceResolvers(resolvers);
|
||||
|
||||
PathPattern staticResources = new PathPatternParser().parse("/resources/*.css");
|
||||
this.handlerMap.put(staticResources, otherHandler);
|
||||
this.handlerMap.put("/resources/*.css", otherHandler);
|
||||
this.urlProvider.setHandlerMap(this.handlerMap);
|
||||
|
||||
String url = this.urlProvider.getForLookupPath("/resources/foo.css").blockMillis(5000);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ package org.springframework.web.reactive.result.method;
|
|||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
|
@ -39,6 +41,7 @@ import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
|||
import org.springframework.web.server.session.MockWebSessionManager;
|
||||
import org.springframework.web.server.session.WebSessionManager;
|
||||
import org.springframework.web.util.patterns.PathPattern;
|
||||
import org.springframework.web.util.patterns.PathPatternComparator;
|
||||
import org.springframework.web.util.patterns.PathPatternParser;
|
||||
import org.springframework.web.util.patterns.PatternComparatorConsideringPath;
|
||||
|
||||
|
|
@ -54,7 +57,7 @@ public class HandlerMethodMappingTests {
|
|||
|
||||
private PathPatternParser patternParser = new PathPatternParser();
|
||||
|
||||
private AbstractHandlerMethodMapping<PathPattern> mapping;
|
||||
private AbstractHandlerMethodMapping<String> mapping;
|
||||
|
||||
private MyHandler handler;
|
||||
|
||||
|
|
@ -74,14 +77,14 @@ public class HandlerMethodMappingTests {
|
|||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void registerDuplicates() {
|
||||
this.mapping.registerMapping(this.patternParser.parse("/foo"), this.handler, this.method1);
|
||||
this.mapping.registerMapping(this.patternParser.parse("/foo"), this.handler, this.method2);
|
||||
this.mapping.registerMapping("/foo", this.handler, this.method1);
|
||||
this.mapping.registerMapping("/foo", this.handler, this.method2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void directMatch() throws Exception {
|
||||
String key = "foo";
|
||||
this.mapping.registerMapping(this.patternParser.parse(key), this.handler, this.method1);
|
||||
String key = "/foo";
|
||||
this.mapping.registerMapping(key, this.handler, this.method1);
|
||||
Mono<Object> result = this.mapping.getHandler(createExchange(HttpMethod.GET, key));
|
||||
|
||||
assertEquals(this.method1, ((HandlerMethod) result.block()).getMethod());
|
||||
|
|
@ -89,8 +92,8 @@ public class HandlerMethodMappingTests {
|
|||
|
||||
@Test
|
||||
public void patternMatch() throws Exception {
|
||||
this.mapping.registerMapping(this.patternParser.parse("/fo*"), this.handler, this.method1);
|
||||
this.mapping.registerMapping(this.patternParser.parse("/f*"), this.handler, this.method2);
|
||||
this.mapping.registerMapping("/fo*", this.handler, this.method1);
|
||||
this.mapping.registerMapping("/f*", this.handler, this.method2);
|
||||
|
||||
Mono<Object> result = this.mapping.getHandler(createExchange(HttpMethod.GET, "/foo"));
|
||||
assertEquals(this.method1, ((HandlerMethod) result.block()).getMethod());
|
||||
|
|
@ -98,8 +101,8 @@ public class HandlerMethodMappingTests {
|
|||
|
||||
@Test
|
||||
public void ambiguousMatch() throws Exception {
|
||||
this.mapping.registerMapping(this.patternParser.parse("/f?o"), this.handler, this.method1);
|
||||
this.mapping.registerMapping(this.patternParser.parse("/fo?"), this.handler, this.method2);
|
||||
this.mapping.registerMapping("/f?o", this.handler, this.method1);
|
||||
this.mapping.registerMapping("/fo?", this.handler, this.method2);
|
||||
Mono<Object> result = this.mapping.getHandler(createExchange(HttpMethod.GET, "/foo"));
|
||||
|
||||
StepVerifier.create(result).expectError(IllegalStateException.class).verify();
|
||||
|
|
@ -107,8 +110,8 @@ public class HandlerMethodMappingTests {
|
|||
|
||||
@Test
|
||||
public void registerMapping() throws Exception {
|
||||
PathPattern key1 = this.patternParser.parse("/foo");
|
||||
PathPattern key2 = this.patternParser.parse("/foo*");
|
||||
String key1 = "/foo";
|
||||
String key2 = "/foo*";
|
||||
this.mapping.registerMapping(key1, this.handler, this.method1);
|
||||
this.mapping.registerMapping(key2, this.handler, this.method2);
|
||||
|
||||
|
|
@ -118,8 +121,8 @@ public class HandlerMethodMappingTests {
|
|||
|
||||
@Test
|
||||
public void registerMappingWithSameMethodAndTwoHandlerInstances() throws Exception {
|
||||
PathPattern key1 = this.patternParser.parse("/foo");
|
||||
PathPattern key2 = this.patternParser.parse("/bar");
|
||||
String key1 = "/foo";
|
||||
String key2 = "/bar";
|
||||
MyHandler handler1 = new MyHandler();
|
||||
MyHandler handler2 = new MyHandler();
|
||||
this.mapping.registerMapping(key1, handler1, this.method1);
|
||||
|
|
@ -131,13 +134,13 @@ public class HandlerMethodMappingTests {
|
|||
|
||||
@Test
|
||||
public void unregisterMapping() throws Exception {
|
||||
String key = "foo";
|
||||
this.mapping.registerMapping(this.patternParser.parse(key), this.handler, this.method1);
|
||||
String key = "/foo";
|
||||
this.mapping.registerMapping(key, this.handler, this.method1);
|
||||
Mono<Object> result = this.mapping.getHandler(createExchange(HttpMethod.GET, key));
|
||||
|
||||
assertNotNull(result.block());
|
||||
|
||||
this.mapping.unregisterMapping(this.patternParser.parse(key));
|
||||
this.mapping.unregisterMapping(key);
|
||||
result = this.mapping.getHandler(createExchange(HttpMethod.GET, key));
|
||||
|
||||
assertNull(result.block());
|
||||
|
|
@ -152,7 +155,7 @@ public class HandlerMethodMappingTests {
|
|||
}
|
||||
|
||||
|
||||
private static class MyHandlerMethodMapping extends AbstractHandlerMethodMapping<PathPattern> {
|
||||
private static class MyHandlerMethodMapping extends AbstractHandlerMethodMapping<String> {
|
||||
|
||||
private PathPatternParser patternParser = new PathPatternParser();
|
||||
|
||||
|
|
@ -162,28 +165,34 @@ public class HandlerMethodMappingTests {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected PathPattern getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
protected String getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
String methodName = method.getName();
|
||||
return methodName.startsWith("handler") ? this.patternParser.parse(methodName) : null;
|
||||
return methodName.startsWith("handler") ? methodName : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SortedSet<PathPattern> getMappingPathPatterns(PathPattern key) {
|
||||
TreeSet<PathPattern> patterns = new TreeSet<>();
|
||||
patterns.add(key);
|
||||
return patterns;
|
||||
protected Set<String> getMappingPathPatterns(String key) {
|
||||
return Collections.singleton(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PathPattern getMatchingMapping(PathPattern pattern, ServerWebExchange exchange) {
|
||||
protected String getMatchingMapping(String pattern, ServerWebExchange exchange) {
|
||||
String lookupPath = exchange.getRequest().getURI().getPath();
|
||||
return (pattern.matches(lookupPath) ? pattern : null);
|
||||
PathPattern pathPattern = this.patternParser.parse(pattern);
|
||||
return (pathPattern.matches(lookupPath) ? pattern : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Comparator<PathPattern> getMappingComparator(ServerWebExchange exchange) {
|
||||
protected Comparator<String> getMappingComparator(ServerWebExchange exchange) {
|
||||
String lookupPath = exchange.getRequest().getURI().getPath();
|
||||
return new PatternComparatorConsideringPath(lookupPath);
|
||||
PatternComparatorConsideringPath comparator = new PatternComparatorConsideringPath(lookupPath);
|
||||
return new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
|
||||
return comparator.compare(patternParser.parse(o1), patternParser.parse(o2));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
|
|
@ -98,11 +96,10 @@ public class RequestMappingInfoHandlerMappingTests {
|
|||
public void getMappingPathPatterns() throws Exception {
|
||||
String[] patterns = {"/foo/*", "/foo", "/bar/*", "/bar"};
|
||||
RequestMappingInfo info = paths(patterns).build();
|
||||
Set<PathPattern> actual = this.handlerMapping.getMappingPathPatterns(info);
|
||||
Set<String> actual = this.handlerMapping.getMappingPathPatterns(info);
|
||||
|
||||
assertThat(actual.stream().map(PathPattern::getPatternString).collect(Collectors.toList()),
|
||||
Matchers.containsInAnyOrder(new String[]{"/foo/*", "/foo", "/bar/*", "/bar",
|
||||
"/foo/*/", "/foo/", "/bar/*/", "/bar/"}));
|
||||
assertThat(actual, Matchers.containsInAnyOrder("/foo/*", "/foo", "/bar/*", "/bar",
|
||||
"/foo/*/", "/foo/", "/bar/*/", "/bar/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -192,7 +189,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
|||
|
||||
assertError(mono, UnsupportedMediaTypeStatusException.class,
|
||||
ex -> assertEquals("Request failure [status: 415, " +
|
||||
"reason: \"Invalid mime type \"bogus\": does not contain '/'\"]",
|
||||
"reason: \"Invalid mime type \"bogus\": does not contain '/'\"]",
|
||||
ex.getMessage()));
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +235,8 @@ public class RequestMappingInfoHandlerMappingTests {
|
|||
exchange.getAttributes().get(name));
|
||||
}
|
||||
|
||||
@Test @SuppressWarnings("unchecked")
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void handleMatchUriTemplateVariables() throws Exception {
|
||||
String lookupPath = "/1/2";
|
||||
this.request = MockServerHttpRequest.get(lookupPath).build();
|
||||
|
|
@ -370,7 +368,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> void assertError(Mono<Object> mono, final Class<T> exceptionClass, final Consumer<T> consumer) {
|
||||
private <T> void assertError(Mono<Object> mono, final Class<T> exceptionClass, final Consumer<T> consumer) {
|
||||
|
||||
StepVerifier.create(mono)
|
||||
.consumeErrorWith(error -> {
|
||||
|
|
@ -469,11 +467,11 @@ public class RequestMappingInfoHandlerMappingTests {
|
|||
public void foo() {
|
||||
}
|
||||
|
||||
@GetMapping(path = "/foo", params="p")
|
||||
@GetMapping(path = "/foo", params = "p")
|
||||
public void fooParam() {
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/ba*", method = { GET, HEAD })
|
||||
@RequestMapping(path = "/ba*", method = {GET, HEAD})
|
||||
public void bar() {
|
||||
}
|
||||
|
||||
|
|
@ -481,31 +479,31 @@ public class RequestMappingInfoHandlerMappingTests {
|
|||
public void empty() {
|
||||
}
|
||||
|
||||
@PutMapping(path = "/person/{id}", consumes="application/xml")
|
||||
@PutMapping(path = "/person/{id}", consumes = "application/xml")
|
||||
public void consumes(@RequestBody String text) {
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/persons", produces="application/xml")
|
||||
@RequestMapping(path = "/persons", produces = "application/xml")
|
||||
public String produces() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/params", params="foo=bar")
|
||||
@RequestMapping(path = "/params", params = "foo=bar")
|
||||
public String param() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/params", params="bar=baz")
|
||||
@RequestMapping(path = "/params", params = "bar=baz")
|
||||
public String param2() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/content", produces="application/xml")
|
||||
@RequestMapping(path = "/content", produces = "application/xml")
|
||||
public String xmlContent() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/content", produces="!application/xml")
|
||||
@RequestMapping(path = "/content", produces = "!application/xml")
|
||||
public String nonXmlContent() {
|
||||
return "";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue