Skip to content

Commit b248523

Browse files
committed
WIP
Revert previous changes for spring-projectsgh-31104 and apply them on DispatcherServlet
1 parent dc7179c commit b248523

File tree

4 files changed

+57
-33
lines changed

4 files changed

+57
-33
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java

+8
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,14 @@ protected ModelAndView processHandlerException(HttpServletRequest request, HttpS
13381338

13391339
// Success and error responses may use different content types
13401340
request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
1341+
// Reset the response if the response is not committed already
1342+
// throws an exception and skips error handling entirely otherwise
1343+
try {
1344+
response.reset();
1345+
}
1346+
catch (IllegalStateException illegalStateException) {
1347+
throw ex;
1348+
}
13411349

13421350
// Check registered HandlerExceptionResolvers...
13431351
ModelAndView exMv = null;

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,9 @@ protected ModelAndView doResolveHandlerMethodException(HttpServletRequest reques
401401

402402
ServletWebRequest webRequest = new ServletWebRequest(request, response);
403403
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
404+
404405
ArrayList<Throwable> exceptions = new ArrayList<>();
405406
try {
406-
response.reset();
407407
if (logger.isDebugEnabled()) {
408408
logger.debug("Using @ExceptionHandler " + exceptionHandlerMethod);
409409
}

spring-webmvc/src/test/java/org/springframework/web/servlet/DispatcherServletTests.java

+48
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,15 @@
7070
import static org.assertj.core.api.Assertions.assertThat;
7171
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
7272
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
73+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
7374
import static org.mockito.ArgumentMatchers.anyString;
7475
import static org.mockito.Mockito.never;
7576
import static org.mockito.Mockito.spy;
7677
import static org.mockito.Mockito.verify;
7778

7879
/**
80+
* Tests for {@link DispatcherServlet}.
81+
*
7982
* @author Rod Johnson
8083
* @author Juergen Hoeller
8184
* @author Rob Harrop
@@ -887,6 +890,39 @@ public void webDavMethod() throws Exception {
887890
assertThat(response.getContentAsString()).isEqualTo("body");
888891
}
889892

893+
@Test
894+
public void shouldResetResponseIfNotCommitted() throws Exception {
895+
StaticWebApplicationContext context = new StaticWebApplicationContext();
896+
context.setServletContext(getServletContext());
897+
context.registerSingleton("/error", ErrorController.class);
898+
DispatcherServlet servlet = new DispatcherServlet(context);
899+
servlet.init(servletConfig);
900+
901+
MockHttpServletRequest request = new MockHttpServletRequest(getServletContext(), "GET", "/error");
902+
MockHttpServletResponse response = new MockHttpServletResponse();
903+
assertThatThrownBy(() -> servlet.service(request, response)).isInstanceOf(ServletException.class)
904+
.hasCauseInstanceOf(IllegalArgumentException.class);
905+
assertThat(response.getContentAsByteArray()).isEmpty();
906+
assertThat(response.getStatus()).isEqualTo(200);
907+
}
908+
909+
@Test
910+
public void shouldAttemptToResetResponseIfCommitted() throws Exception {
911+
StaticWebApplicationContext context = new StaticWebApplicationContext();
912+
context.setServletContext(getServletContext());
913+
context.registerSingleton("/error", ErrorController.class);
914+
DispatcherServlet servlet = new DispatcherServlet(context);
915+
servlet.init(servletConfig);
916+
917+
MockHttpServletRequest request = new MockHttpServletRequest(getServletContext(), "GET", "/error");
918+
request.setAttribute("commit", true);
919+
MockHttpServletResponse response = new MockHttpServletResponse();
920+
assertThatThrownBy(() -> servlet.service(request, response)).isInstanceOf(ServletException.class)
921+
.hasCauseInstanceOf(IllegalArgumentException.class);
922+
assertThat(response.getContentAsByteArray()).isNotEmpty();
923+
assertThat(response.getStatus()).isEqualTo(400);
924+
}
925+
890926

891927
public static class ControllerFromParent implements Controller {
892928

@@ -934,4 +970,16 @@ public SimpleUrlHandlerMapping handlerMapping() {
934970
}
935971
}
936972

973+
private static class ErrorController implements Controller {
974+
@Override
975+
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
976+
response.setStatus(400);
977+
if (request.getAttribute("commit") != null) {
978+
response.flushBuffer();
979+
}
980+
response.getWriter().write("error");
981+
throw new IllegalArgumentException("test error");
982+
}
983+
}
984+
937985
}

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolverTests.java

-32
Original file line numberDiff line numberDiff line change
@@ -385,38 +385,6 @@ void resolveExceptionViaMappedHandler() throws Exception {
385385
assertExceptionHandledAsBody(mav, "DefaultTestExceptionResolver: IllegalStateException");
386386
}
387387

388-
@Test // gh-30702
389-
void attemptToResetResponseBeforeResolveException() throws Exception {
390-
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyControllerAdviceConfig.class);
391-
this.resolver.setMappedHandlerClasses(HttpRequestHandler.class);
392-
this.resolver.setApplicationContext(ctx);
393-
this.resolver.afterPropertiesSet();
394-
395-
IllegalStateException ex = new IllegalStateException();
396-
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
397-
this.response.getWriter().print("test");
398-
ModelAndView mav = this.resolver.resolveException(this.request, this.response, handler, ex);
399-
400-
assertExceptionHandledAsBody(mav, "DefaultTestExceptionResolver: IllegalStateException");
401-
}
402-
403-
@Test // gh-30702
404-
void attemptToResetResponseBeforeResolveExceptionFails() throws Exception {
405-
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyControllerAdviceConfig.class);
406-
this.resolver.setMappedHandlerClasses(HttpRequestHandler.class);
407-
this.resolver.setApplicationContext(ctx);
408-
this.resolver.afterPropertiesSet();
409-
410-
IllegalStateException ex = new IllegalStateException();
411-
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
412-
this.response.getWriter().print("test");
413-
this.response.setCommitted(true);
414-
ModelAndView mav = this.resolver.resolveException(this.request, this.response, handler, ex);
415-
416-
assertThat(mav).as("Exception was handled").isNull();
417-
assertThat(this.response.getContentAsString()).isEqualTo("test");
418-
}
419-
420388

421389
private void assertMethodProcessorCount(int resolverCount, int handlerCount) {
422390
assertThat(this.resolver.getArgumentResolvers().getResolvers()).hasSize(resolverCount);

0 commit comments

Comments
 (0)