Refactor HandlerMapping path match configuration
Since the introduction of `PathPatternRegistry`, the various path match configuration flags are no longer needed in several places and that configuration can live in the registry itself. Issue: SPR-14544
This commit is contained in:
@@ -19,8 +19,10 @@ package org.springframework.web.reactive.config;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -51,6 +53,7 @@ import org.springframework.validation.Validator;
|
||||
import org.springframework.web.bind.support.WebBindingInitializer;
|
||||
import org.springframework.web.bind.support.WebExchangeDataBinder;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
|
||||
import org.springframework.web.reactive.handler.AbstractHandlerMapping;
|
||||
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
|
||||
@@ -70,6 +73,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON;
|
||||
import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM;
|
||||
@@ -102,9 +106,9 @@ public class WebFluxConfigurationSupportTests {
|
||||
|
||||
assertEquals(0, mapping.getOrder());
|
||||
|
||||
assertFalse(mapping.useSuffixPatternMatch());
|
||||
assertFalse(mapping.useRegisteredSuffixPatternMatch());
|
||||
assertTrue(mapping.useTrailingSlashMatch());
|
||||
assertFalse(mapping.getPatternRegistry().useSuffixPatternMatch());
|
||||
assertThat(mapping.getPatternRegistry().getFileExtensions(), Matchers.empty());
|
||||
assertTrue(mapping.getPatternRegistry().useTrailingSlashMatch());
|
||||
|
||||
name = "webFluxContentTypeResolver";
|
||||
RequestedContentTypeResolver resolver = context.getBean(name, RequestedContentTypeResolver.class);
|
||||
@@ -126,8 +130,9 @@ public class WebFluxConfigurationSupportTests {
|
||||
RequestMappingHandlerMapping mapping = context.getBean(name, RequestMappingHandlerMapping.class);
|
||||
assertNotNull(mapping);
|
||||
|
||||
assertFalse(mapping.useSuffixPatternMatch());
|
||||
assertFalse(mapping.useTrailingSlashMatch());
|
||||
assertFalse(mapping.getPatternRegistry().useTrailingSlashMatch());
|
||||
assertTrue(mapping.getPatternRegistry().useSuffixPatternMatch());
|
||||
assertThat(mapping.getPatternRegistry().getFileExtensions(), Matchers.contains(".json", ".xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -306,8 +311,15 @@ public class WebFluxConfigurationSupportTests {
|
||||
|
||||
@Override
|
||||
public void configurePathMatching(PathMatchConfigurer configurer) {
|
||||
configurer.setUseSuffixPatternMatch(false);
|
||||
configurer.setUseTrailingSlashMatch(false);
|
||||
configurer.setUseSuffixPatternMatch(true);
|
||||
configurer.setUseRegisteredSuffixPatternMatch(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
|
||||
builder.mediaType("json", MediaType.APPLICATION_JSON);
|
||||
builder.mediaType("xml", MediaType.APPLICATION_XML);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
@@ -30,6 +29,7 @@ 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.PathPattern;
|
||||
import org.springframework.web.util.patterns.PathPatternRegistry;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -119,7 +119,8 @@ public class PatternsRequestConditionTests {
|
||||
assertNotNull(match);
|
||||
assertEquals("/{foo}", match.getPatterns().iterator().next().getPatternString());
|
||||
|
||||
condition = new PatternsRequestCondition(new String[] {"/foo"}, null, true, false, null);
|
||||
condition = new PatternsRequestCondition(new String[] {"/foo"}, null,
|
||||
createPatternRegistry(true, false, null));
|
||||
match = condition.getMatchingCondition(exchange);
|
||||
|
||||
assertNotNull(match);
|
||||
@@ -132,7 +133,8 @@ public class PatternsRequestConditionTests {
|
||||
public void matchSuffixPatternUsingFileExtensions() throws Exception {
|
||||
String[] patterns = new String[] {"/jobs/{jobName}"};
|
||||
Set<String> extensions = Collections.singleton("json");
|
||||
PatternsRequestCondition condition = new PatternsRequestCondition(patterns, null, true, false, extensions);
|
||||
PatternsRequestCondition condition = new PatternsRequestCondition(patterns, null,
|
||||
createPatternRegistry(true, false, extensions));
|
||||
|
||||
ServerWebExchange exchange = createExchange("/jobs/my.job");
|
||||
PatternsRequestCondition match = condition.getMatchingCondition(exchange);
|
||||
@@ -152,10 +154,12 @@ public class PatternsRequestConditionTests {
|
||||
@Test
|
||||
public void matchSuffixPatternUsingFileExtensions2() throws Exception {
|
||||
PatternsRequestCondition condition1 = new PatternsRequestCondition(
|
||||
new String[] {"/prefix"}, null, true, false, Collections.singleton("json"));
|
||||
new String[] {"/prefix"}, null,
|
||||
createPatternRegistry(true, false, Collections.singleton("json")));
|
||||
|
||||
PatternsRequestCondition condition2 = new PatternsRequestCondition(
|
||||
new String[] {"/suffix"}, null, true, false, null);
|
||||
new String[] {"/suffix"}, null,
|
||||
createPatternRegistry(true, false, null));
|
||||
|
||||
PatternsRequestCondition combined = condition1.combine(condition2);
|
||||
|
||||
@@ -174,14 +178,16 @@ public class PatternsRequestConditionTests {
|
||||
|
||||
assertNull("Should not match by default", match);
|
||||
|
||||
condition = new PatternsRequestCondition(new String[] {"/foo"}, null, false, true, null);
|
||||
condition = new PatternsRequestCondition(new String[] {"/foo"}, null,
|
||||
createPatternRegistry(false, true, null));
|
||||
match = condition.getMatchingCondition(exchange);
|
||||
|
||||
assertNotNull(match);
|
||||
assertEquals("Trailing slash should be insensitive to useSuffixPatternMatch settings (SPR-6164, SPR-5636)",
|
||||
"/foo/", match.getPatterns().iterator().next().getPatternString());
|
||||
|
||||
condition = new PatternsRequestCondition(new String[] {"/foo"}, null, true, true, null);
|
||||
condition = new PatternsRequestCondition(new String[] {"/foo"}, null,
|
||||
createPatternRegistry(true, true, null));
|
||||
match = condition.getMatchingCondition(exchange);
|
||||
|
||||
assertNotNull(match);
|
||||
@@ -232,4 +238,13 @@ public class PatternsRequestConditionTests {
|
||||
return new DefaultServerWebExchange(request, new MockServerHttpResponse());
|
||||
}
|
||||
|
||||
private PathPatternRegistry createPatternRegistry(boolean useSuffixPatternMatch, boolean useTrailingSlashMatch,
|
||||
Set<String> extensions) {
|
||||
PathPatternRegistry registry = new PathPatternRegistry();
|
||||
registry.setUseSuffixPatternMatch(useSuffixPatternMatch);
|
||||
registry.setUseTrailingSlashMatch(useTrailingSlashMatch);
|
||||
registry.setFileExtensions(extensions);
|
||||
return registry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
import org.springframework.web.server.support.HttpRequestPathHelper;
|
||||
import org.springframework.web.util.patterns.PathPattern;
|
||||
import org.springframework.web.util.patterns.PathPatternRegistry;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -545,10 +546,12 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
RequestMapping annot = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
|
||||
if (annot != null) {
|
||||
PathPatternRegistry pathPatternRegistry = new PathPatternRegistry();
|
||||
pathPatternRegistry.setUseSuffixPatternMatch(true);
|
||||
pathPatternRegistry.setUseTrailingSlashMatch(true);
|
||||
BuilderConfiguration options = new BuilderConfiguration();
|
||||
options.setPathHelper(getPathHelper());
|
||||
options.setSuffixPatternMatch(true);
|
||||
options.setTrailingSlashMatch(true);
|
||||
options.setPathPatternRegistry(pathPatternRegistry);
|
||||
return paths(annot.value()).methods(annot.method())
|
||||
.params(annot.params()).headers(annot.headers())
|
||||
.consumes(annot.consumes()).produces(annot.produces())
|
||||
|
||||
@@ -22,10 +22,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
@@ -43,19 +40,12 @@ import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.reactive.accept.MappingContentTypeResolver;
|
||||
import org.springframework.web.reactive.result.method.RequestMappingInfo;
|
||||
import org.springframework.web.util.patterns.PathPattern;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.contains;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link RequestMappingHandlerMapping}.
|
||||
@@ -74,59 +64,6 @@ public class RequestMappingHandlerMappingTests {
|
||||
this.handlerMapping.setApplicationContext(wac);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void useRegisteredSuffixPatternMatch() {
|
||||
assertFalse(this.handlerMapping.useSuffixPatternMatch());
|
||||
assertFalse(this.handlerMapping.useRegisteredSuffixPatternMatch());
|
||||
|
||||
MappingContentTypeResolver contentTypeResolver = mock(MappingContentTypeResolver.class);
|
||||
when(contentTypeResolver.getKeys()).thenReturn(Collections.singleton("json"));
|
||||
|
||||
this.handlerMapping.setUseSuffixPatternMatch(true);
|
||||
this.handlerMapping.setUseRegisteredSuffixPatternMatch(true);
|
||||
this.handlerMapping.setContentTypeResolver(contentTypeResolver);
|
||||
this.handlerMapping.afterPropertiesSet();
|
||||
|
||||
assertTrue(this.handlerMapping.useSuffixPatternMatch());
|
||||
assertTrue(this.handlerMapping.useRegisteredSuffixPatternMatch());
|
||||
assertEquals(Collections.singleton("json"), this.handlerMapping.getFileExtensions());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useRegisteredSuffixPatternMatchInitialization() {
|
||||
MappingContentTypeResolver contentTypeResolver = mock(MappingContentTypeResolver.class);
|
||||
when(contentTypeResolver.getKeys()).thenReturn(Collections.singleton("json"));
|
||||
|
||||
final Set<String> actualExtensions = new HashSet<>();
|
||||
RequestMappingHandlerMapping localHandlerMapping = new RequestMappingHandlerMapping() {
|
||||
@Override
|
||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
actualExtensions.addAll(getFileExtensions());
|
||||
return super.getMappingForMethod(method, handlerType);
|
||||
}
|
||||
};
|
||||
this.wac.registerSingleton("testController", ComposedAnnotationController.class);
|
||||
this.wac.refresh();
|
||||
|
||||
localHandlerMapping.setContentTypeResolver(contentTypeResolver);
|
||||
localHandlerMapping.setUseRegisteredSuffixPatternMatch(true);
|
||||
localHandlerMapping.setApplicationContext(this.wac);
|
||||
localHandlerMapping.afterPropertiesSet();
|
||||
|
||||
assertEquals(Collections.singleton("json"), actualExtensions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useSuffixPatternMatch() {
|
||||
assertFalse(this.handlerMapping.useSuffixPatternMatch());
|
||||
assertFalse(this.handlerMapping.useRegisteredSuffixPatternMatch());
|
||||
|
||||
this.handlerMapping.setUseRegisteredSuffixPatternMatch(true);
|
||||
assertTrue("'true' registeredSuffixPatternMatch should enable suffixPatternMatch",
|
||||
this.handlerMapping.useSuffixPatternMatch());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveEmbeddedValuesInPatterns() {
|
||||
this.handlerMapping.setEmbeddedValueResolver(
|
||||
|
||||
Reference in New Issue
Block a user