Remove warning about empty @RequestMapping path

See gh-22543
This commit is contained in:
Rossen Stoyanchev 2019-04-09 13:12:35 -04:00
parent 5b17bb2e14
commit f839c1f9cd
8 changed files with 15 additions and 66 deletions

View File

@ -94,10 +94,8 @@ public @interface RequestMapping {
* <p><b>Supported at the type level as well as at the method level!</b> * <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit * When used at the type level, all method-level mappings inherit
* this primary mapping, narrowing it for a specific handler method. * this primary mapping, narrowing it for a specific handler method.
* <p><strong>NOTE</strong>: Each handler method must be mapped to a * <p><strong>NOTE</strong>: A handler method that is not mapped to any path
* non-empty path, either at the type level, at the method level, or a * explicitly, is effectively mapped to an empty path.
* combination of the two. If you wish to map to all paths, please map
* explicitly to {@code "/**"} or {@code "**"}.
*/ */
@AliasFor("path") @AliasFor("path")
String[] value() default {}; String[] value() default {};
@ -111,10 +109,8 @@ public @interface RequestMapping {
* <p><b>Supported at the type level as well as at the method level!</b> * <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit * When used at the type level, all method-level mappings inherit
* this primary mapping, narrowing it for a specific handler method. * this primary mapping, narrowing it for a specific handler method.
* <p><strong>NOTE</strong>: Each handler method must be mapped to a * <p><strong>NOTE</strong>: A handler method that is not mapped to any path
* non-empty path, either at the type level, at the method level, or a * explicitly, is effectively mapped to an empty path.
* combination of the two. If you wish to map to all paths, please map
* explicitly to {@code "/**"} or {@code "**"}.
* @since 4.2 * @since 4.2
*/ */
@AliasFor("value") @AliasFor("value")

View File

@ -41,14 +41,12 @@ import org.springframework.http.server.RequestPath;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsUtils; import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.handler.AbstractHandlerMapping; import org.springframework.web.reactive.handler.AbstractHandlerMapping;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.pattern.PathPattern;
/** /**
* Abstract base class for {@link HandlerMapping} implementations that define * Abstract base class for {@link HandlerMapping} implementations that define
@ -415,12 +413,6 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
@Nullable @Nullable
protected abstract T getMappingForMethod(Method method, Class<?> handlerType); protected abstract T getMappingForMethod(Method method, Class<?> handlerType);
/**
* Extract and return the URL path patterns contained in the supplied mapping.
* @since 5.2
*/
protected abstract Set<PathPattern> getMappingPathPatterns(T mapping);
/** /**
* Check if a mapping matches the current request and return a (potentially * Check if a mapping matches the current request and return a (potentially
* new) mapping with conditions relevant to the current request. * new) mapping with conditions relevant to the current request.
@ -507,16 +499,6 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
} }
private void validateMethodMapping(HandlerMethod handlerMethod, T mapping) { private void validateMethodMapping(HandlerMethod handlerMethod, T mapping) {
// Log a warning if the supplied mapping maps the supplied HandlerMethod
// only to empty paths.
if (logger.isWarnEnabled() && getMappingPathPatterns(mapping).stream()
.map(PathPattern::getPatternString).noneMatch(StringUtils::hasText)) {
logger.warn(String.format(
"Handler method '%s' in bean '%s' is not mapped to an explicit path. " +
"If you wish to map to all paths, please map explicitly to \"/**\" or \"**\".",
handlerMethod, handlerMethod.getBean()));
}
// Assert that the supplied mapping is unique. // Assert that the supplied mapping is unique.
HandlerMethod existingHandlerMethod = this.mappingLookup.get(mapping); HandlerMethod existingHandlerMethod = this.mappingLookup.get(mapping);
if (existingHandlerMethod != null && !existingHandlerMethod.equals(handlerMethod)) { if (existingHandlerMethod != null && !existingHandlerMethod.equals(handlerMethod)) {

View File

@ -68,15 +68,6 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
} }
/**
* Get the URL path patterns associated with the supplied {@link RequestMappingInfo}.
* @since 5.2
*/
@Override
protected Set<PathPattern> getMappingPathPatterns(RequestMappingInfo info) {
return info.getPatternsCondition().getPatterns();
}
/** /**
* Check if the given RequestMappingInfo matches the current request and * Check if the given RequestMappingInfo matches the current request and
* return a (potentially new) instance with conditions that match the * return a (potentially new) instance with conditions that match the

View File

@ -17,9 +17,7 @@
package org.springframework.web.reactive.result.method; package org.springframework.web.reactive.result.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Set;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Before; import org.junit.Before;
@ -37,10 +35,7 @@ import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.pattern.PathPattern; import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser; import org.springframework.web.util.pattern.PathPatternParser;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
/** /**
* Unit tests for {@link AbstractHandlerMethodMapping}. * Unit tests for {@link AbstractHandlerMethodMapping}.
@ -158,11 +153,6 @@ public class HandlerMethodMappingTests {
return methodName.startsWith("handler") ? methodName : null; return methodName.startsWith("handler") ? methodName : null;
} }
@Override
protected Set<PathPattern> getMappingPathPatterns(String mapping) {
return Collections.emptySet();
}
@Override @Override
protected String getMatchingMapping(String pattern, ServerWebExchange exchange) { protected String getMatchingMapping(String pattern, ServerWebExchange exchange) {
PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication(); PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication();

View File

@ -43,7 +43,6 @@ import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsUtils; import org.springframework.web.cors.CorsUtils;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
@ -616,15 +615,6 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
} }
private void validateMethodMapping(HandlerMethod handlerMethod, T mapping) { private void validateMethodMapping(HandlerMethod handlerMethod, T mapping) {
// Log a warning if the supplied mapping maps the supplied HandlerMethod
// only to empty paths.
if (logger.isWarnEnabled() && getMappingPathPatterns(mapping).stream().noneMatch(StringUtils::hasText)) {
logger.warn(String.format(
"Handler method '%s' in bean '%s' is not mapped to an explicit path. " +
"If you wish to map to all paths, please map explicitly to \"/**\" or \"**\".",
handlerMethod, handlerMethod.getBean()));
}
// Assert that the supplied mapping is unique. // Assert that the supplied mapping is unique.
HandlerMethod existingHandlerMethod = this.mappingLookup.get(mapping); HandlerMethod existingHandlerMethod = this.mappingLookup.get(mapping);
if (existingHandlerMethod != null && !existingHandlerMethod.equals(handlerMethod)) { if (existingHandlerMethod != null && !existingHandlerMethod.equals(handlerMethod)) {

View File

@ -78,7 +78,7 @@ public class RequestMappingInfoHandlerMappingTests {
private HandlerMethod barMethod; private HandlerMethod barMethod;
private HandlerMethod rootMethod; private HandlerMethod emptyMethod;
@Before @Before
@ -88,7 +88,7 @@ public class RequestMappingInfoHandlerMappingTests {
this.fooMethod = new HandlerMethod(testController, "foo"); this.fooMethod = new HandlerMethod(testController, "foo");
this.fooParamMethod = new HandlerMethod(testController, "fooParam"); this.fooParamMethod = new HandlerMethod(testController, "fooParam");
this.barMethod = new HandlerMethod(testController, "bar"); this.barMethod = new HandlerMethod(testController, "bar");
this.rootMethod = new HandlerMethod(testController, "root"); this.emptyMethod = new HandlerMethod(testController, "empty");
this.handlerMapping = new TestRequestMappingInfoHandlerMapping(); this.handlerMapping = new TestRequestMappingInfoHandlerMapping();
this.handlerMapping.registerHandler(testController); this.handlerMapping.registerHandler(testController);
@ -125,12 +125,12 @@ public class RequestMappingInfoHandlerMappingTests {
MockHttpServletRequest request = new MockHttpServletRequest("GET", ""); MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
HandlerMethod handlerMethod = getHandler(request); HandlerMethod handlerMethod = getHandler(request);
assertEquals(this.rootMethod.getMethod(), handlerMethod.getMethod()); assertEquals(this.emptyMethod.getMethod(), handlerMethod.getMethod());
request = new MockHttpServletRequest("GET", "/"); request = new MockHttpServletRequest("GET", "/");
handlerMethod = getHandler(request); handlerMethod = getHandler(request);
assertEquals(this.rootMethod.getMethod(), handlerMethod.getMethod()); assertEquals(this.emptyMethod.getMethod(), handlerMethod.getMethod());
} }
@Test @Test
@ -465,8 +465,8 @@ public class RequestMappingInfoHandlerMappingTests {
public void bar() { public void bar() {
} }
@RequestMapping("/") @RequestMapping("")
public void root() { public void empty() {
} }
@RequestMapping(value = "/person/{id}", method = RequestMethod.PUT, consumes="application/xml") @RequestMapping(value = "/person/{id}", method = RequestMethod.PUT, consumes="application/xml")

View File

@ -228,7 +228,7 @@ public class RequestMappingHandlerMappingTests {
@RequestMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
static class ComposedAnnotationController { static class ComposedAnnotationController {
@RequestMapping("/**") @RequestMapping
public void handle() { public void handle() {
} }

View File

@ -2016,7 +2016,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
@Controller @Controller
static class ControllerWithEmptyValueMapping { static class ControllerWithEmptyValueMapping {
@RequestMapping("/**") @RequestMapping("")
public void myPath2(HttpServletResponse response) throws IOException { public void myPath2(HttpServletResponse response) throws IOException {
throw new IllegalStateException("test"); throw new IllegalStateException("test");
} }
@ -2035,7 +2035,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
@Controller @Controller
private static class ControllerWithErrorThrown { private static class ControllerWithErrorThrown {
@RequestMapping("/**") @RequestMapping("")
public void myPath2(HttpServletResponse response) throws IOException { public void myPath2(HttpServletResponse response) throws IOException {
throw new AssertionError("test"); throw new AssertionError("test");
} }
@ -3629,7 +3629,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
@Controller @Controller
static class HttpHeadersResponseController { static class HttpHeadersResponseController {
@RequestMapping(value = "/*", method = RequestMethod.POST) @RequestMapping(value = "", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED) @ResponseStatus(HttpStatus.CREATED)
public HttpHeaders create() throws URISyntaxException { public HttpHeaders create() throws URISyntaxException {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();