From c6134184514a319e04dfe52012b07d359ac748c0 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 24 Sep 2019 16:01:18 +0100 Subject: [PATCH] Suppress body when handling a no content (204) "error" Fixes gh-18136 --- .../servlet/error/BasicErrorController.java | 5 +++- .../BasicErrorControllerMockMvcTests.java | 27 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java index aa3726b8e3..07d652490e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java @@ -94,8 +94,11 @@ public class BasicErrorController extends AbstractErrorController { @RequestMapping public ResponseEntity> error(HttpServletRequest request) { - Map body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL)); HttpStatus status = getStatus(request); + if (status == HttpStatus.NO_CONTENT) { + return new ResponseEntity>(status); + } + Map body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL)); return new ResponseEntity<>(body, status); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java index 72b93c4bfc..b182fbc80c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java @@ -92,13 +92,23 @@ public class BasicErrorControllerMockMvcTests { } @Test - public void testErrorWithResponseStatus() throws Exception { + public void testErrorWithNotFoundResponseStatus() throws Exception { MvcResult result = this.mockMvc.perform(get("/bang")).andExpect(status().isNotFound()).andReturn(); MvcResult response = this.mockMvc.perform(new ErrorDispatcher(result, "/error")).andReturn(); String content = response.getResponse().getContentAsString(); assertThat(content).contains("Expected!"); } + @Test + public void testErrorWithNoContentResponseStatus() throws Exception { + MvcResult result = this.mockMvc.perform(get("/noContent").accept("some/thing")) + .andExpect(status().isNoContent()).andReturn(); + MvcResult response = this.mockMvc.perform(new ErrorDispatcher(result, "/error")) + .andExpect(status().isNoContent()).andReturn(); + String content = response.getResponse().getContentAsString(); + assertThat(content).isEmpty(); + } + @Test public void testBindingExceptionForMachineClient() throws Exception { // In a real server the response is carried over into the error dispatcher, but @@ -174,6 +184,11 @@ public class BasicErrorControllerMockMvcTests { throw error; } + @RequestMapping("/noContent") + public void noContent() throws Exception { + throw new NoContentException("Expected!"); + } + } } @@ -187,6 +202,15 @@ public class BasicErrorControllerMockMvcTests { } + @ResponseStatus(HttpStatus.NO_CONTENT) + private static class NoContentException extends RuntimeException { + + NoContentException(String string) { + super(string); + } + + } + private class ErrorDispatcher implements RequestBuilder { private MvcResult result; @@ -203,6 +227,7 @@ public class BasicErrorControllerMockMvcTests { MockHttpServletRequest request = this.result.getRequest(); request.setDispatcherType(DispatcherType.ERROR); request.setRequestURI(this.path); + request.setAttribute("javax.servlet.error.status_code", this.result.getResponse().getStatus()); return request; }