mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Align BasicErrorController’s HTML response status with non-HTML status
Previously, BasicErrorController would return the response status set in the javax.servlet.error.status_code request attribute when serving JSON but would also return a 200 OK response when serving HTML. This didn’t cause much trouble when a person was browsing, but proved problematic for machine clients that request text/html and care about the response status. For example, the success handler would be driven for an XHR request even though the response was really an error. This commit updates BasicErrorController to set the response status for text/html responses to match the status that it would use in an application/json response. Closes gh-4694
This commit is contained in:
parent
b36fe2cbd8
commit
ce541bebcf
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.web;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
||||||
@ -61,7 +62,9 @@ public class BasicErrorController implements ErrorController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "${error.path:/error}", produces = "text/html")
|
@RequestMapping(value = "${error.path:/error}", produces = "text/html")
|
||||||
public ModelAndView errorHtml(HttpServletRequest request) {
|
public ModelAndView errorHtml(HttpServletRequest request,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
response.setStatus(getStatus(request).value());
|
||||||
return new ModelAndView("error", getErrorAttributes(request, false));
|
return new ModelAndView("error", getErrorAttributes(request, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public class BasicErrorControllerDirectMockMvcTests {
|
|||||||
.run("--server.port=0"));
|
.run("--server.port=0"));
|
||||||
MvcResult response = this.mockMvc
|
MvcResult response = this.mockMvc
|
||||||
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
||||||
.andExpect(status().isOk()).andReturn();
|
.andExpect(status().is5xxServerError()).andReturn();
|
||||||
String content = response.getResponse().getContentAsString();
|
String content = response.getResponse().getContentAsString();
|
||||||
assertTrue("Wrong content: " + content, content.contains("status=999"));
|
assertTrue("Wrong content: " + content, content.contains("status=999"));
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ public class BasicErrorControllerDirectMockMvcTests {
|
|||||||
WebMvcIncludedConfiguration.class).run("--server.port=0"));
|
WebMvcIncludedConfiguration.class).run("--server.port=0"));
|
||||||
MvcResult response = this.mockMvc
|
MvcResult response = this.mockMvc
|
||||||
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
||||||
.andExpect(status().isOk()).andReturn();
|
.andExpect(status().is5xxServerError()).andReturn();
|
||||||
String content = response.getResponse().getContentAsString();
|
String content = response.getResponse().getContentAsString();
|
||||||
assertTrue("Wrong content: " + content, content.contains("status=999"));
|
assertTrue("Wrong content: " + content, content.contains("status=999"));
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ public class BasicErrorControllerDirectMockMvcTests {
|
|||||||
WithAopConfiguration.class).run("--server.port=0"));
|
WithAopConfiguration.class).run("--server.port=0"));
|
||||||
MvcResult response = this.mockMvc
|
MvcResult response = this.mockMvc
|
||||||
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
||||||
.andExpect(status().isOk()).andReturn();
|
.andExpect(status().is5xxServerError()).andReturn();
|
||||||
String content = response.getResponse().getContentAsString();
|
String content = response.getResponse().getContentAsString();
|
||||||
assertTrue("Wrong content: " + content, content.contains("status=999"));
|
assertTrue("Wrong content: " + content, content.contains("status=999"));
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ public class BasicErrorControllerMockMvcTests {
|
|||||||
public void testDirectAccessForBrowserClient() throws Exception {
|
public void testDirectAccessForBrowserClient() throws Exception {
|
||||||
MvcResult response = this.mockMvc
|
MvcResult response = this.mockMvc
|
||||||
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
||||||
.andExpect(status().isOk()).andReturn();
|
.andExpect(status().is5xxServerError()).andReturn();
|
||||||
String content = response.getResponse().getContentAsString();
|
String content = response.getResponse().getContentAsString();
|
||||||
assertTrue("Wrong content: " + content, content.contains("ERROR_BEAN"));
|
assertTrue("Wrong content: " + content, content.contains("ERROR_BEAN"));
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ public class DefaultErrorViewIntegrationTests {
|
|||||||
public void testErrorForBrowserClient() throws Exception {
|
public void testErrorForBrowserClient() throws Exception {
|
||||||
MvcResult response = this.mockMvc
|
MvcResult response = this.mockMvc
|
||||||
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
.perform(get("/error").accept(MediaType.TEXT_HTML))
|
||||||
.andExpect(status().isOk()).andReturn();
|
.andExpect(status().is5xxServerError()).andReturn();
|
||||||
String content = response.getResponse().getContentAsString();
|
String content = response.getResponse().getContentAsString();
|
||||||
assertTrue("Wrong content: " + content, content.contains("<html>"));
|
assertTrue("Wrong content: " + content, content.contains("<html>"));
|
||||||
assertTrue("Wrong content: " + content, content.contains("999"));
|
assertTrue("Wrong content: " + content, content.contains("999"));
|
||||||
@ -83,7 +83,7 @@ public class DefaultErrorViewIntegrationTests {
|
|||||||
new RuntimeException(
|
new RuntimeException(
|
||||||
"<script>alert('Hello World')</script>"))
|
"<script>alert('Hello World')</script>"))
|
||||||
.accept(MediaType.TEXT_HTML))
|
.accept(MediaType.TEXT_HTML))
|
||||||
.andExpect(status().isOk()).andReturn();
|
.andExpect(status().is5xxServerError()).andReturn();
|
||||||
String content = response.getResponse().getContentAsString();
|
String content = response.getResponse().getContentAsString();
|
||||||
assertTrue("Wrong content: " + content, content.contains("<script>"));
|
assertTrue("Wrong content: " + content, content.contains("<script>"));
|
||||||
assertTrue("Wrong content: " + content, content.contains("Hello World"));
|
assertTrue("Wrong content: " + content, content.contains("Hello World"));
|
||||||
|
@ -89,7 +89,7 @@ public class SampleActuatorUiApplicationTests {
|
|||||||
ResponseEntity<String> entity = new TestRestTemplate().exchange(
|
ResponseEntity<String> entity = new TestRestTemplate().exchange(
|
||||||
"http://localhost:" + this.port + "/error", HttpMethod.GET,
|
"http://localhost:" + this.port + "/error", HttpMethod.GET,
|
||||||
new HttpEntity<Void>(headers), String.class);
|
new HttpEntity<Void>(headers), String.class);
|
||||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, entity.getStatusCode());
|
||||||
assertTrue("Wrong body:\n" + entity.getBody(),
|
assertTrue("Wrong body:\n" + entity.getBody(),
|
||||||
entity.getBody().contains("<html>"));
|
entity.getBody().contains("<html>"));
|
||||||
assertTrue("Wrong body:\n" + entity.getBody(),
|
assertTrue("Wrong body:\n" + entity.getBody(),
|
||||||
|
Loading…
Reference in New Issue
Block a user