Method level only, empty RequestMapping matches "" and "/"
Closes gh-30293
This commit is contained in:
parent
3fb98b6a97
commit
bbab4faf7a
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -48,15 +48,12 @@ public class DefaultControllerSpecTests {
|
|||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("Success");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void controllerEmptyPath() {
|
||||
new DefaultControllerSpec(new MyController()).build()
|
||||
.get().uri("")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("Success empty path");
|
||||
.expectBody(String.class).isEqualTo("Success");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -121,19 +118,15 @@ public class DefaultControllerSpecTests {
|
|||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RestController
|
||||
private static class MyController {
|
||||
|
||||
@GetMapping("/")
|
||||
@GetMapping
|
||||
public String handleRootPath() {
|
||||
return "Success";
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String handleEmptyPath() {
|
||||
return "Success empty path";
|
||||
}
|
||||
|
||||
@GetMapping("/exception")
|
||||
public void handleWithError() {
|
||||
throw new IllegalStateException();
|
||||
|
|
|
@ -89,8 +89,12 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
|||
return " || ";
|
||||
}
|
||||
|
||||
private boolean isEmptyPathMapping() {
|
||||
return this.patterns == EMPTY_PATH_PATTERN;
|
||||
/**
|
||||
* Whether the condition is the "" (empty path) mapping.
|
||||
* @since 6.0.10
|
||||
*/
|
||||
public boolean isEmptyPathMapping() {
|
||||
return (this.patterns == EMPTY_PATH_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -153,6 +153,9 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
|
|||
if (typeInfo != null) {
|
||||
info = typeInfo.combine(info);
|
||||
}
|
||||
if (info.getPatternsCondition().isEmptyPathMapping()) {
|
||||
info = info.mutate().paths("", "/").options(this.config).build();
|
||||
}
|
||||
for (Map.Entry<String, Predicate<Class<?>>> entry : this.pathPrefixes.entrySet()) {
|
||||
if (entry.getValue().test(handlerType)) {
|
||||
String prefix = entry.getKey();
|
||||
|
|
|
@ -61,6 +61,17 @@ class RequestMappingIntegrationTests extends AbstractRequestMappingIntegrationTe
|
|||
}
|
||||
|
||||
|
||||
@ParameterizedHttpServerTest // gh-30293
|
||||
void emptyMapping(HttpServer httpServer) throws Exception {
|
||||
startServer(httpServer);
|
||||
|
||||
String url = "http://localhost:" + this.port;
|
||||
assertThat(getRestTemplate().getForObject(url, String.class)).isEqualTo("root");
|
||||
|
||||
url += "/";
|
||||
assertThat(getRestTemplate().getForObject(url, String.class)).isEqualTo("root");
|
||||
}
|
||||
|
||||
@ParameterizedHttpServerTest
|
||||
void httpHead(HttpServer httpServer) throws Exception {
|
||||
startServer(httpServer);
|
||||
|
@ -106,6 +117,11 @@ class RequestMappingIntegrationTests extends AbstractRequestMappingIntegrationTe
|
|||
@SuppressWarnings("unused")
|
||||
private static class TestRestController {
|
||||
|
||||
@GetMapping
|
||||
public String get() {
|
||||
return "root";
|
||||
}
|
||||
|
||||
@GetMapping("/text")
|
||||
public String textGet() {
|
||||
return "Foo";
|
||||
|
|
|
@ -255,6 +255,16 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
|
|||
pprc.getPatternValues() : ((PatternsRequestCondition) condition).getPatterns());
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the request mapping has an empty URL path mapping.
|
||||
* @since 6.0.10
|
||||
*/
|
||||
public boolean isEmptyMapping() {
|
||||
RequestCondition<?> condition = getActivePatternsCondition();
|
||||
return (condition instanceof PathPatternsRequestCondition pprc ?
|
||||
pprc.isEmptyPathMapping() : ((PatternsRequestCondition) condition).isEmptyPathMapping());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the HTTP request methods of this {@link RequestMappingInfo};
|
||||
* or instance with 0 request methods (never {@code null}).
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -305,6 +305,9 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
|
|||
if (typeInfo != null) {
|
||||
info = typeInfo.combine(info);
|
||||
}
|
||||
if (info.isEmptyMapping()) {
|
||||
info = info.mutate().paths("", "/").options(this.config).build();
|
||||
}
|
||||
String prefix = getPathPrefix(handlerType);
|
||||
if (prefix != null) {
|
||||
info = RequestMappingInfo.paths(prefix).options(this.config).build().combine(info);
|
||||
|
|
|
@ -192,7 +192,16 @@ class ServletAnnotationControllerHandlerMethodTests extends AbstractServletHandl
|
|||
request.setServletPath("");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
|
||||
assertThat(response.getContentAsString()).isEqualTo("test");
|
||||
|
||||
// gh-30293
|
||||
request = new MockHttpServletRequest("GET", "/");
|
||||
response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
|
||||
assertThat(response.getContentAsString()).isEqualTo("test");
|
||||
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
|
|
Loading…
Reference in New Issue