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 7824625d711..97ea9c56b49 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 dd543a50bfb..5a3e876376e 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 @@ -90,13 +90,23 @@ class BasicErrorControllerMockMvcTests { } @Test - void testErrorWithResponseStatus() throws Exception { + 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 + 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 void testBindingExceptionForMachineClient() throws Exception { // In a real server the response is carried over into the error dispatcher, but @@ -168,6 +178,11 @@ class BasicErrorControllerMockMvcTests { throw error; } + @RequestMapping("/noContent") + void noContent() throws Exception { + throw new NoContentException("Expected!"); + } + public String getFoo() { return "foo"; } @@ -185,6 +200,15 @@ 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; @@ -201,6 +225,7 @@ 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; }