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>
posted @ 2021-12-31 14:04  山河永慕~  阅读(469)  评论(0编辑  收藏  举报