SpringBoot - 自定义错误页2(进阶:简单地自定义Error数据、Error视图)
二、简单地自定义 Error 数据、Error 视图
1,自定义 Error 数据
我们知道 Spring Boot 返回的错误信息一共 5 条,分别是:timestamp、status、error、message、path。如果需要增加自定义的错误信息,只需要自定义一个 ErrorAttributes 即可。
(1)首先继承 DefaultErrorAttributes 创建一个自定义的 ErrorAttributes:
自定义的 ErrorAttributes 类添加 @Component 注解,该类将被注册到 Spring 容器中。
重写 DefaultErrorAttributes 的 getErrorAttributes 方法,方法中先获取 Spring Boot 默认提供的错误信息,然后在此基础上添加或者移除 Error 信息。
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.stereotype.Component; import org.springframework.web.context.request.WebRequest; import java.util.Map; @Component public class MyErrorAttribute extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace); // 获取 Spring Boot 默认提供的错误信息 errorAttributes.put("msg", "出错了!出错了!"); // 添加一个自定义的错误信息 errorAttributes.remove("error"); // 移除一个默认的错误信息 return errorAttributes; } }
(2)创建编辑 resource/templates/4xx.html 文件,内容如下。同前文的区别在于多了自定义错误显示的显示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1"> <tr> <td>msg</td> <td th:text="${msg}"></td> </tr> <tr> <td>timestamp</td> <td th:text="${timestamp}"></td> </tr> <tr> <td>status</td> <td th:text="${status}"></td> </tr> <tr> <td>error</td> <td th:text="${error}"></td> </tr> <tr> <td>message</td> <td th:text="${message}"></td> </tr> <tr> <td>path</td> <td th:text="${path}"></td> </tr> </table> </body> </html>
(3)当我们使用浏览器访问一个不存在的接口,运行结果如下。可以看到自定义错误信息已经成功显示,同时由于默认的 error 信息被我们移除,因此就不显示。访问地址localhost:8080/zhangsan
(4)如果通过 Postman 等工具来发起这个请求,那么会发现返回的 JSON 数据同样发生了变化(少了 error,多了 msg)。
2,自定义 Error 视图
Error 视图说明:
如果发生错误,在 BasicErrorController 的 errorHtml 方法中会调用 resolveErrorView 方法获取一个 ModelAndView 实例,作为 Error 视图展示给用户。
而 resolveErrorView 方法是 ErrorViewResolver 提供的。Spring Boot 默认采用的 ErrorViewResolver 是 DefaultErrorViewResolver,它会自动在 error 目录下寻找 4xx.html、5xx.html...这样的页面。
如果我们想要自定义 Error 视图,只需要提供自己的 ErrorViewResolver 即可。
(1)首先实现 ErrorViewResolver 接口创建一个自定义的 ErrorViewResolver:
- 自定义的 ErrorViewResolver 类添加 @Component 注解,该类将被注册到 Spring 容器中。
- 实现 ErrorViewResolver 接口 的 resolveErrorView 方法,方法中返回一个 ModelAndView,并且在其中设置 Error 视图和 Error 数据。
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.util.Map; @Component public class MyErrorViewResolver implements ErrorViewResolver { @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { // 自定义一个 ModelAndView,并且在其中设置 Error 视图和 Error 数据 ModelAndView mv = new ModelAndView("errorPage"); mv.addObject("msg", "出错了!出错了!"); // 添加一个自定义的错误信息 mv.addAllObjects(model); // 加入Spring Boot提供的默认5条错误信息 return mv; } }
(2)创建编辑 resource/templates/errorPage.html 文件,内容同上面的一样:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1"> <tr> <td>msg</td> <td th:text="${msg}"></td> </tr> <tr> <td>timestamp</td> <td th:text="${timestamp}"></td> </tr> <tr> <td>status</td> <td th:text="${status}"></td> </tr> <tr> <td>error</td> <td th:text="${error}"></td> </tr> <tr> <td>message</td> <td th:text="${message}"></td> </tr> <tr> <td>path</td> <td th:text="${path}"></td> </tr> </table> </body> </html>
(3)当我们使用浏览器访问一个不存在的接口,运行结果如下。可以看到自定义错误信息已经成功显示:
(4)由于我们是实现 resolveErrorView 方法,如果通过 Postman 等工具来发起这个请求,可以发现返回的 JSON 数据是没有变化的。
<!DOCTYPE html>
<
html
lang
=
"en"
>
<
head
>
<
meta
charset
=
"UTF-8"
>
<
title
>Title</
title
>
</
head
>
<
body
>
<
table
border
=
"1"
>
<
tr
>
<
td
>msg</
td
>
<
td
th:text
=
"${msg}"
></
td
>
</
tr
>
<
tr
>
<
td
>timestamp</
td
>
<
td
th:text
=
"${timestamp}"
></
td
>
</
tr
>
<
tr
>
<
td
>status</
td
>
<
td
th:text
=
"${status}"
></
td
>
</
tr
>
<
tr
>
<
td
>error</
td
>
<
td
th:text
=
"${error}"
></
td
>
</
tr
>
<
tr
>
<
td
>message</
td
>
<
td
th:text
=
"${message}"
></
td
>
</
tr
>
<
tr
>
<
td
>path</
td
>
<
td
th:text
=
"${path}"
></
td
>
</
tr
>
</
table
>
</
body
>
</
html
>
早年同窗始相知,三载瞬逝情却萌。年少不知愁滋味,犹读红豆生南国。别离方知相思苦,心田红豆根以生。