Attempt to reset Servlet response in DispatcherServlet

This is a follow-up change related to gh-31104.
This change reverts the changes previously made in
`ExceptionHandlerExceptionResolver` and instead attempts to reset the
response directly in `DispatcherServlet` in order to cover all types or
exception handling.

Unlike the previous change, we decided to continue even if the response
was already committed: exception handlers will have a chance to be
called, even if it means they'll have to operate on a garbled response.
This change will cause less disruption, in case existing exception
handlers were relying on this behavior.

See gh-31104
This commit is contained in:
Brian Clozel
2023-08-30 15:42:15 +02:00
parent 32f128b6ba
commit 0d7c9b7c93
4 changed files with 56 additions and 33 deletions

View File

@@ -1338,6 +1338,13 @@ public class DispatcherServlet extends FrameworkServlet {
// Success and error responses may use different content types
request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
// Reset the response if the response is not committed already
try {
response.reset();
}
catch (IllegalStateException illegalStateException) {
// the response is already committed, leave it to exception handlers anyway
}
// Check registered HandlerExceptionResolvers...
ModelAndView exMv = null;

View File

@@ -401,9 +401,9 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
ServletWebRequest webRequest = new ServletWebRequest(request, response);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
ArrayList<Throwable> exceptions = new ArrayList<>();
try {
response.reset();
if (logger.isDebugEnabled()) {
logger.debug("Using @ExceptionHandler " + exceptionHandlerMethod);
}