Adapt to trailing slashes no longer being matched by default
See gh-31563
This commit is contained in:
@@ -180,8 +180,9 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
|
||||
private void registerLinksMapping() {
|
||||
String path = this.endpointMapping.getPath();
|
||||
String linksPath = StringUtils.hasLength(path) ? path : "/";
|
||||
String[] produces = StringUtils.toStringArray(this.endpointMediaTypes.getProduced());
|
||||
RequestMappingInfo mapping = RequestMappingInfo.paths(path).methods(RequestMethod.GET).produces(produces)
|
||||
RequestMappingInfo mapping = RequestMappingInfo.paths(linksPath).methods(RequestMethod.GET).produces(produces)
|
||||
.build();
|
||||
LinksHandler linksHandler = getLinksHandler();
|
||||
registerMapping(mapping, linksHandler,
|
||||
|
||||
@@ -240,9 +240,11 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin
|
||||
}
|
||||
|
||||
private void registerLinksMapping() {
|
||||
RequestMappingInfo mapping = RequestMappingInfo.paths(this.endpointMapping.createSubPath(""))
|
||||
.methods(RequestMethod.GET).produces(this.endpointMediaTypes.getProduced().toArray(new String[0]))
|
||||
.options(this.builderConfig).build();
|
||||
String path = this.endpointMapping.getPath();
|
||||
String linksPath = (StringUtils.hasLength(path)) ? this.endpointMapping.createSubPath("/") : "/";
|
||||
RequestMappingInfo mapping = RequestMappingInfo.paths(linksPath).methods(RequestMethod.GET)
|
||||
.produces(this.endpointMediaTypes.getProduced().toArray(new String[0])).options(this.builderConfig)
|
||||
.build();
|
||||
LinksHandler linksHandler = getLinksHandler();
|
||||
registerMapping(mapping, linksHandler, ReflectionUtils.findMethod(linksHandler.getClass(), "links",
|
||||
HttpServletRequest.class, HttpServletResponse.class));
|
||||
|
||||
@@ -123,9 +123,9 @@ public abstract class AbstractWebEndpointIntegrationTests<T extends Configurable
|
||||
}
|
||||
|
||||
@Test
|
||||
void operationWithTrailingSlashShouldMatch() {
|
||||
load(TestEndpointConfiguration.class, (client) -> client.get().uri("/test/").exchange().expectStatus().isOk()
|
||||
.expectBody().jsonPath("All").isEqualTo(true));
|
||||
void operationWithTrailingSlashShouldNotMatch() {
|
||||
load(TestEndpointConfiguration.class,
|
||||
(client) -> client.get().uri("/test/").exchange().expectStatus().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -30,6 +30,8 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.web.servlet.DefaultWebMvcTagsProvider;
|
||||
import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsContributor;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -69,6 +71,22 @@ class DefaultWebMvcTagsProviderTests {
|
||||
assertThat(tags).containsOnlyKeys("method", "uri", "alpha", "bravo", "charlie");
|
||||
}
|
||||
|
||||
@Test
|
||||
void trailingSlashIsIncludedByDefault() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/the/uri/");
|
||||
request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "{one}/{two}/");
|
||||
Map<String, Tag> tags = asMap(new DefaultWebMvcTagsProvider().getTags(request, null, null, null));
|
||||
assertThat(tags.get("uri").getValue()).isEqualTo("{one}/{two}/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void trailingSlashCanBeIgnored() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/the/uri/");
|
||||
request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "{one}/{two}/");
|
||||
Map<String, Tag> tags = asMap(new DefaultWebMvcTagsProvider(true).getTags(request, null, null, null));
|
||||
assertThat(tags.get("uri").getValue()).isEqualTo("{one}/{two}");
|
||||
}
|
||||
|
||||
private Map<String, Tag> asMap(Iterable<Tag> tags) {
|
||||
return StreamSupport.stream(tags.spliterator(), false)
|
||||
.collect(Collectors.toMap(Tag::getKey, Function.identity()));
|
||||
|
||||
@@ -77,7 +77,10 @@ import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
@@ -312,6 +315,7 @@ class WebMvcMetricsFilterTests {
|
||||
|
||||
@Test
|
||||
void trailingSlashShouldNotRecordDuplicateMetrics() throws Exception {
|
||||
|
||||
this.mvc.perform(get("/api/c1/simple/10")).andExpect(status().isOk());
|
||||
this.mvc.perform(get("/api/c1/simple/10/")).andExpect(status().isOk());
|
||||
assertThat(this.registry.get("http.server.requests").tags("status", "200", "uri", "/api/c1/simple/{id}").timer()
|
||||
@@ -328,7 +332,7 @@ class WebMvcMetricsFilterTests {
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableWebMvc
|
||||
@Import({ Controller1.class, Controller2.class })
|
||||
static class MetricsFilterApp {
|
||||
static class MetricsFilterApp implements WebMvcConfigurer {
|
||||
|
||||
@Bean
|
||||
Clock micrometerClock() {
|
||||
@@ -393,6 +397,14 @@ class WebMvcMetricsFilterTests {
|
||||
return new FaultyWebMvcTagsProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void configurePathMatch(PathMatchConfigurer configurer) {
|
||||
PathPatternParser pathPatternParser = new PathPatternParser();
|
||||
pathPatternParser.setMatchOptionalTrailingSeparator(true);
|
||||
configurer.setPatternParser(pathPatternParser);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
|
||||
Reference in New Issue
Block a user