From 9a4df5a97da322070476d979c929a98f431a2e60 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Tue, 14 Feb 2023 20:13:15 +0000 Subject: [PATCH] DefaultHandlerExceptionResolver respects custom ModelAndView Closes gh-29971 --- .../DefaultHandlerExceptionResolver.java | 5 ++-- .../DefaultHandlerExceptionResolverTests.java | 27 ++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java index 11bbce9859..9a4f93d635 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java @@ -212,9 +212,8 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes (AsyncRequestTimeoutException) ex, request, response, handler); } - if (mav == null) { - return handleErrorResponse((ErrorResponse) ex, request, response, handler); - } + return (mav != null ? mav : + handleErrorResponse((ErrorResponse) ex, request, response, handler)); } // Other, lower level exceptions diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java index cf248b9bb5..7c9e07e8c6 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.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. @@ -20,6 +20,8 @@ import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collections; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -32,6 +34,7 @@ import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.lang.Nullable; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindException; import org.springframework.web.HttpMediaTypeNotSupportedException; @@ -42,6 +45,7 @@ import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.ServletRequestBindingException; import org.springframework.web.context.request.async.AsyncRequestTimeoutException; import org.springframework.web.multipart.support.MissingServletRequestPartException; +import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.NoHandlerFoundException; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; @@ -232,6 +236,27 @@ public class DefaultHandlerExceptionResolverTests { assertThat(response.getStatus()).as("Invalid status code").isEqualTo(503); } + @Test + public void customModelAndView() { + ModelAndView expected = new ModelAndView(); + + HandlerExceptionResolver resolver = new DefaultHandlerExceptionResolver() { + + @Override + protected ModelAndView handleHttpRequestMethodNotSupported( + HttpRequestMethodNotSupportedException ex, HttpServletRequest request, + HttpServletResponse response, @Nullable Object handler) { + + return expected; + } + }; + + HttpRequestMethodNotSupportedException ex = new HttpRequestMethodNotSupportedException("GET"); + + ModelAndView actual = resolver.resolveException(request, response, null, ex); + assertThat(actual).isSameAs(expected); + } + @SuppressWarnings("unused") public void handle(String arg) {