Skip to content

Commit c613418

Browse files
committed
Suppress body when handling a no content (204) "error"
Fixes gh-18136
1 parent 35ad5cd commit c613418

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,11 @@ public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse re
9494

9595
@RequestMapping
9696
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
97-
Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
9897
HttpStatus status = getStatus(request);
98+
if (status == HttpStatus.NO_CONTENT) {
99+
return new ResponseEntity<Map<String, Object>>(status);
100+
}
101+
Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
99102
return new ResponseEntity<>(body, status);
100103
}
101104

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,23 @@ public void testDirectAccessForMachineClient() throws Exception {
9292
}
9393

9494
@Test
95-
public void testErrorWithResponseStatus() throws Exception {
95+
public void testErrorWithNotFoundResponseStatus() throws Exception {
9696
MvcResult result = this.mockMvc.perform(get("/bang")).andExpect(status().isNotFound()).andReturn();
9797
MvcResult response = this.mockMvc.perform(new ErrorDispatcher(result, "/error")).andReturn();
9898
String content = response.getResponse().getContentAsString();
9999
assertThat(content).contains("Expected!");
100100
}
101101

102+
@Test
103+
public void testErrorWithNoContentResponseStatus() throws Exception {
104+
MvcResult result = this.mockMvc.perform(get("/noContent").accept("some/thing"))
105+
.andExpect(status().isNoContent()).andReturn();
106+
MvcResult response = this.mockMvc.perform(new ErrorDispatcher(result, "/error"))
107+
.andExpect(status().isNoContent()).andReturn();
108+
String content = response.getResponse().getContentAsString();
109+
assertThat(content).isEmpty();
110+
}
111+
102112
@Test
103113
public void testBindingExceptionForMachineClient() throws Exception {
104114
// In a real server the response is carried over into the error dispatcher, but
@@ -174,6 +184,11 @@ public String bind() throws Exception {
174184
throw error;
175185
}
176186

187+
@RequestMapping("/noContent")
188+
public void noContent() throws Exception {
189+
throw new NoContentException("Expected!");
190+
}
191+
177192
}
178193

179194
}
@@ -187,6 +202,15 @@ private static class NotFoundException extends RuntimeException {
187202

188203
}
189204

205+
@ResponseStatus(HttpStatus.NO_CONTENT)
206+
private static class NoContentException extends RuntimeException {
207+
208+
NoContentException(String string) {
209+
super(string);
210+
}
211+
212+
}
213+
190214
private class ErrorDispatcher implements RequestBuilder {
191215

192216
private MvcResult result;
@@ -203,6 +227,7 @@ public MockHttpServletRequest buildRequest(ServletContext servletContext) {
203227
MockHttpServletRequest request = this.result.getRequest();
204228
request.setDispatcherType(DispatcherType.ERROR);
205229
request.setRequestURI(this.path);
230+
request.setAttribute("javax.servlet.error.status_code", this.result.getResponse().getStatus());
206231
return request;
207232
}
208233

0 commit comments

Comments
 (0)