spring|各大一线互联网公司还在用SpringBoot这是为什么?( 三 )


静态异常页面自定义静态异常页面 , 又分为两种 , 第一种 是使用HTTP响应码来命名页面 , 例如404.html、405.html、500.html .... , 另一种就是直接定义一个 4xx.html , 表示400-499 的状态都显示这个异常页面 , 5xx.html 表示 500-599 的状态显示这个异常页面 。
默认是在 classpath:/static/error/ 路径下定义相关页面:
此时 , 启动项目 , 如果项目抛出 500 请求错误 , 就会自动展示 500.html 这个页面 , 发生 404 就会展示404.html 页面 。 如果异常展示页面既存在 5xx.html , 也存在 500.html, 此时 , 发生500异常时 , 优先展示 500.html 页面 。
动态异常页面
动态的异常页面定义方式和静态的基本 一致 , 可以采用的页面模板有 jsp、freemarker、thymeleaf 。
动态异常页面 , 也支持 404.html 或者 4xx.html, 但是一般来说 , 由于动态异常页面可以直接展示异常详细信息 , 所以就没有必要挨个枚举错误了, 直接定义 4xx.html(这里使用thymeleaf模板)或者5xx.html 即可 。
注意 , 动态页面模板 , 不需要开发者自己去定义控制器 , 直接定义异常页面即可, Spring Boot 中自带的异常处理器会自动查找到异常页面 。
页面定义如下:

页面内容如下:
<!DOCTYPE html><html lang=\"en\" xmlns:th=\"http://www.thymeleaf.org\"><head><meta charset=\"UTF-8\"><title>Title</title></head><body><h1>5xx</h1><table border=\"1\"><tr><td>path</td><td th:text=\"${path\"></td></tr><tr><td>error</td><td th:text=\"${error\"></td></tr><tr><td>message</td><td th:text=\"${message\"></td></tr><tr><td>timestamp</td><td th:text=\"${timestamp\"></td></tr><tr><td>status</td><td th:text=\"${status\"></td></tr></table></body></html>
默认情况下 , 完整的异常信息就是这5条 , 展示 效果如下 :

如果动态页面和静态页面同时定义了异常处理页面 , 例如 classpath:/static/error/404.html 和classpath:/templates/error/404.html 同时存在时 , 默认使用动态页面 。 即完整的错误页面查找
方式应该是这样:
发生了 500 错误-->查找动态 500.html 页面-->查找静态 500.html --> 查找动态 5xx.html-->查找静态5xx.html 。
自定义异常数据
默认情况下 , 在 Spring Boot 中 , 所有的异常数据其实就是上文所展示出来的 5 条数据 , 这 5 条数据定义在 org.springframework.boot.web.reactive.error.DefaultErrorAttributes 类中 , 具体定义在 getErrorAttributes 方法中 :
public Map<String Object> getErrorAttributes(ServerRequest requestboolean includeStackTrace) {Map<String Object> errorAttributes = new LinkedHashMap<>();errorAttributes.put(\"timestamp\" new Date());errorAttributes.put(\"path\" request.path());Throwable error = getError(request);HttpStatus errorStatus = determineHttpStatus(error);errorAttributes.put(\"status\" errorStatus.value());errorAttributes.put(\"error\" errorStatus.getReasonPhrase());errorAttributes.put(\"message\" determineMessage(error));handleException(errorAttributes determineException(error)includeStackTrace);return errorAttributes;
DefaultErrorAttributes 类本身则是在