From e9e5fee1491f04aad2a23ba4743937d68b836e49 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 11 Sep 2024 15:51:01 +0200 Subject: [PATCH] Consistently resolve exceptions for resources and handler functions Closes gh-33381 --- ...bstractHandlerMethodExceptionResolver.java | 23 ++++++++----------- .../ExceptionHandlerExceptionResolver.java | 10 ++++++-- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java index c9ef0b85de20..90d6e7256ed8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodExceptionResolver.java @@ -22,7 +22,6 @@ import org.springframework.lang.Nullable; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.function.HandlerFunction; /** * Abstract base class for @@ -30,28 +29,24 @@ * implementations that support handling exceptions from handlers of type {@link HandlerMethod}. * * @author Rossen Stoyanchev + * @author Juergen Hoeller * @since 3.1 */ public abstract class AbstractHandlerMethodExceptionResolver extends AbstractHandlerExceptionResolver { /** - * Checks if the handler is a {@link HandlerMethod} or a {@link HandlerFunction} - * and then delegates to the base class implementation of {@code #shouldApplyTo(HttpServletRequest, Object)} - * passing the bean of the {@code HandlerMethod}. Otherwise, returns {@code false}. + * Checks if the handler is a {@link HandlerMethod} or the resolver has global exception + * handlers and then delegates to the base class implementation of {@code #shouldApplyTo} + * passing the bean of the {@code HandlerMethod} if necessary. Otherwise, returns {@code false}. + * @see HandlerMethod + * @see #hasGlobalExceptionHandlers() */ @Override protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) { - if (handler == null) { - return super.shouldApplyTo(request, null); + if (handler instanceof HandlerMethod handlerMethod) { + return super.shouldApplyTo(request, handlerMethod.getBean()); } - else if (handler instanceof HandlerMethod handlerMethod) { - handler = handlerMethod.getBean(); - return super.shouldApplyTo(request, handler); - } - else if (handler instanceof HandlerFunction handlerFunction) { - return super.shouldApplyTo(request, handlerFunction); - } - else if (hasGlobalExceptionHandlers() && hasHandlerMappings()) { + else if (handler == null || (hasGlobalExceptionHandlers() && hasHandlerMappings())) { return super.shouldApplyTo(request, handler); } else { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java index 9e201d4a8a55..93f8356d884e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java @@ -60,6 +60,7 @@ import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.View; +import org.springframework.web.servlet.function.HandlerFunction; import org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; @@ -419,8 +420,13 @@ protected boolean hasGlobalExceptionHandlers() { @Override protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) { - return (handler instanceof ResourceHttpRequestHandler ? - hasGlobalExceptionHandlers() : super.shouldApplyTo(request, handler)); + if ((handler instanceof ResourceHttpRequestHandler || handler instanceof HandlerFunction) && + hasGlobalExceptionHandlers() && !hasHandlerMappings()) { + return true; // apply to ResourceHttpRequestHandler and HandlerFunction by default + } + else { + return super.shouldApplyTo(request, handler); + } } /**