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
广告
将在 10 秒后关闭
bannerAds