Spring Boot 的白标错误页面和 JSON 响应
在Spring Boot的默认状态下,当出现404 Not Found等错误时,会显示一个名为Whitelabel Error Page的错误页面。
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Nov 18 22:16:56 JST 2019
There was an unexpected error (type=Not Found, status=404).
No message available
要确认curl以相同方式工作,请在请求头部使用-H选项指定accept: text/html。
$ curl -H "accept: text/html" http://localhost:8080/
<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>Mon Nov 18 22:18:01 JST 2019</div><div>There was an unexpected error (type=Not Found, status=404).</div><div>No message available</div></body></html>
如果不带-H选项,则会返回JSON格式的数据。
$ curl http://localhost:8080/
{"timestamp":"2019-11-18T13:19:03.320+0000","status":404,"error":"Not Found","message":"No message available","path":"/"}
在Spring Boot文档中写道,机器客户端生成JSON响应,而浏览器客户端则生成HTML格式以显示whitelabel错误视图。
Spring Boot参考文档
对于机器客户端,它生成一个带有错误详情、HTTP状态和异常信息的JSON响应。对于浏览器客户端,有一个“白标签”错误视图,以HTML格式呈现相同的数据(要自定义它,添加一个解析为错误的视图)。
Spring Boot使用BasicErrorController类来处理错误页面。
在BasicErrorController类的errorHtml方法中,使用了@RequestMapping注解,并指定了produces = MediaType.TEXT_HTML_VALUE。
如果请求的 Accept 头中包含 text/html,则调用 errorHtml 方法。
如果请求的 Accept 头中不包含 text/html,则调用 error 方法。
errorHtml方法返回HTML响应,error方法返回JSON响应。
以下是该部分源代码的示例。
spring-boot/BasicErrorController.java 在 v2.2.1.RELEASE 版本的 spring-projects/spring-boot 的 GitHub 上。
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = Collections
.unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
}
@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
if (status == HttpStatus.NO_CONTENT) {
return new ResponseEntity<>(status);
}
Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
return new ResponseEntity<>(body, status);
}
在Spring Boot中,MediaType是一个类,用于表示诸如text/html之类的内容类型。而不是Spring Boot,而是Spring Framework提供了该类。
在GitHub上的spring-projects/spring-framework仓库中的v5.2.1.RELEASE分支下的MediaType.java文件。
/**
* A String equivalent of {@link MediaType#TEXT_HTML}.
*/
public static final String TEXT_HTML_VALUE = "text/html";
以下是您的参考:
参考文献:
参考资料:
-
- Spring Boot エラーページの最低限のカスタマイズ (ErrorController インターフェースの実装) – Qiita
- Spring Boot で 404 Not Found などのエラーが発生した際の表示をカスタマイズする – Qiita