From 089d938e15688b75cc8780a30211bfc84bfbdebf Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Mon, 19 Jun 2023 17:17:38 +0100 Subject: [PATCH] Set throwExceptionIfNoHandlerFound=true and deprecate Closes gh-29491 --- .../pages/web/webmvc/mvc-ann-rest-exceptions.adoc | 4 ++++ .../pages/web/webmvc/mvc-servlet/sequence.adoc | 3 +-- .../client/standalone/ExceptionHandlerTests.java | 3 +-- .../samples/standalone/ExceptionHandlerTests.java | 3 +-- .../web/servlet/DispatcherServlet.java | 7 ++++++- .../web/servlet/ComplexWebApplicationContext.java | 14 ++++++++++---- .../web/servlet/DispatcherServletTests.java | 1 - 7 files changed, 23 insertions(+), 12 deletions(-) diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc index cbbdd951ac88..79329becc28a 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc @@ -162,6 +162,10 @@ Spring MVC exceptions: | (default) | +| `NoResourceFoundException` +| (default) +| + | `TypeMismatchException` | (default) | `+{0}+` property name, `+{1}+` property value diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/sequence.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/sequence.adoc index a640ef3fd869..427a4d0ec139 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/sequence.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-servlet/sequence.adoc @@ -62,8 +62,7 @@ initialization parameters (`init-param` elements) to the Servlet declaration in The exception can then be caught with a `HandlerExceptionResolver` (for example, by using an `@ExceptionHandler` controller method) and handled as any others. - By default, this is set to `false`, in which case the `DispatcherServlet` sets the - response status to 404 (NOT_FOUND) without raising an exception. + As of 6.1, this property is set to `true` and deprecated. Note that, if xref:web/webmvc/mvc-config/default-servlet-handler.adoc[default servlet handling] is also configured, unresolved requests are always forwarded to the default servlet diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ExceptionHandlerTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ExceptionHandlerTests.java index 06b30d0ab24d..b21d1b53cdc0 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ExceptionHandlerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/ExceptionHandlerTests.java @@ -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. @@ -156,7 +156,6 @@ void globalRestPersonControllerExceptionHandlerTakesPrecedenceOverGlobalExceptio void noHandlerFound() { WebTestClient client = MockMvcWebTestClient.bindToController(new RestPersonController()) .controllerAdvice(RestGlobalExceptionHandler.class, RestPersonControllerExceptionHandler.class) - .dispatcherServletCustomizer(servlet -> servlet.setThrowExceptionIfNoHandlerFound(true)) .build(); client.get().uri("/bogus") diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ExceptionHandlerTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ExceptionHandlerTests.java index 059a8138cc3b..f76164c785c4 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ExceptionHandlerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ExceptionHandlerTests.java @@ -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. @@ -138,7 +138,6 @@ void globalRestPersonControllerExceptionHandlerTakesPrecedenceOverGlobalExceptio void noHandlerFound() throws Exception { standaloneSetup(RestPersonController.class) .setControllerAdvice(RestGlobalExceptionHandler.class, RestPersonControllerExceptionHandler.class) - .addDispatcherServletCustomizer(servlet -> servlet.setThrowExceptionIfNoHandlerFound(true)) .build() .perform(get("/bogus").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java index 66a75e4e2ba3..aeb2a025a32f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java @@ -305,7 +305,7 @@ public class DispatcherServlet extends FrameworkServlet { private boolean detectAllViewResolvers = true; /** Throw a NoHandlerFoundException if no Handler was found to process this request? *.*/ - private boolean throwExceptionIfNoHandlerFound = false; + private boolean throwExceptionIfNoHandlerFound = true; /** Perform cleanup of request attributes after include request?. */ private boolean cleanupAfterInclude = true; @@ -467,7 +467,12 @@ public void setDetectAllViewResolvers(boolean detectAllViewResolvers) { *

Default is "false", meaning the DispatcherServlet sends a NOT_FOUND error through the * Servlet response. * @since 4.0 + * @deprecated as of 6.1 this property is set to {@code true} by default, and + * should not need to be customized; in effect, {@link DispatcherServlet} + * should always raise {@link NoHandlerFoundException} and allow it to be + * handled through a {@link HandlerExceptionResolver}. */ + @Deprecated(since = "6.1", forRemoval = true) public void setThrowExceptionIfNoHandlerFound(boolean throwExceptionIfNoHandlerFound) { this.throwExceptionIfNoHandlerFound = throwExceptionIfNoHandlerFound; } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/ComplexWebApplicationContext.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/ComplexWebApplicationContext.java index a21f1935d0cf..0e226cf7c333 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/ComplexWebApplicationContext.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/ComplexWebApplicationContext.java @@ -150,20 +150,26 @@ public void refresh() throws BeansException { registerSingleton("myServlet", MyServlet.class); pvs = new MutablePropertyValues(); - pvs.add("order", "1"); + pvs.add("order", "2"); pvs.add("exceptionMappings", "java.lang.IllegalAccessException=failed2\n" + "ServletRequestBindingException=failed3"); pvs.add("defaultErrorView", "failed0"); - registerSingleton("exceptionResolver1", SimpleMappingExceptionResolver.class, pvs); + registerSingleton("exceptionResolver2", SimpleMappingExceptionResolver.class, pvs); pvs = new MutablePropertyValues(); - pvs.add("order", "0"); + pvs.add("order", "1"); pvs.add("exceptionMappings", "java.lang.Exception=failed1"); pvs.add("mappedHandlers", ManagedList.of(new RuntimeBeanReference("anotherLocaleHandler"))); pvs.add("defaultStatusCode", "500"); pvs.add("defaultErrorView", "failed2"); - registerSingleton("handlerExceptionResolver", SimpleMappingExceptionResolver.class, pvs); + registerSingleton("exceptionResolver1", SimpleMappingExceptionResolver.class, pvs); + + pvs = new MutablePropertyValues(); + pvs.add("order", "0"); + pvs.add("exceptionMappings", "org.springframework.web.servlet.NoHandlerFoundException=notFound"); + pvs.add("defaultStatusCode", "404"); + registerSingleton("exceptionResolver0", SimpleMappingExceptionResolver.class, pvs); registerSingleton("multipartResolver", MockMultipartResolver.class); registerSingleton("testListener", TestApplicationListener.class); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java index 9d3b1c8cd6bf..ce8f96167712 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java @@ -591,7 +591,6 @@ public void throwExceptionIfNoHandlerFound() throws ServletException, IOExceptio DispatcherServlet complexDispatcherServlet = new DispatcherServlet(); complexDispatcherServlet.setContextClass(SimpleWebApplicationContext.class); complexDispatcherServlet.setNamespace("test"); - complexDispatcherServlet.setThrowExceptionIfNoHandlerFound(true); complexDispatcherServlet.init(new MockServletConfig(getServletContext(), "complex")); MockHttpServletRequest request = new MockHttpServletRequest(getServletContext(), "GET", "/unknown");