Spring Boot 自定义错误页面处理


placeholder image
admin 发布于:2022-05-22 21:05:56
阅读:loading

前面已经实现了对全局RestController的JSON格式的统一输出,然而在实际应用中并不是所有的请求都响应为JSON数据,某些应用场景下还是需要使用HTML页面(或JSP)进行响应的,所以本篇文章则是将本站博客系统中的自定义错误页面的实现进行整理实践,也许它们仅是Spring MVC环境的解决方案,但由于身处Spring Boot架构程序中,允许我称之为Spring Boot 的自定义错误页面处理。

1.Controller定义

定义一个Controller,包含两个方法,分别是抛出500的服务器端错误和找不到页面的404错误,代码较为简单,500错误则是简单的除数为0;404则是随意重定向至一个不存在的路径,参考实现如下:

package cn.chendd.modules.error.controller;

import ...;

/**
 * 全局异常验证管理
 * @author chendd
 * @date 2022/5/24 20:35
 */
@Controller
@RequestMapping("/error_page")
@Api(value = "测试错误页面响应验证接口" , tags = {"错误页面应验证"})
public class ErrorPageController extends BaseController {

    @GetMapping("/5xx")
    @ApiOperation(value = "测试错误页面5xx",notes = "测试响应结果集(<b>5xx错误页面</b>)",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public Integer intValue(){
        //500错误
        return 1/0;
    }

    @GetMapping("/4xx")
    @ApiOperation(value = "测试错误页面4xx",notes = "测试响应结果集(<b>4xx错误页面</b>)",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public void stringValue() throws IOException {
        //4xx错误
        response.sendRedirect("/error_page/404");
    }

}

2.默认错误页面显示

image.png

(访问路径:http://localhost:8080/error_page/5xx

image.png

访问路径:http://localhost:8080/error_page/4xx

3.自定义错误页面实现

自定义错误页面的实现主要是分为两个步骤,首先得自定义Bean组件实现ErrorViewResolver接口,重载错误页面的试图逻辑,实现错误页面的自定义,可参考实现逻辑如下:

3.1 ErrorPageCommponent

package cn.chendd.base.spring.components;

import ...;

/**
 * 错误页面定制
 *
 * @author chendd
 * @date 2022/3/7 21:23
 */
@Component
public class ErrorPageCommponent implements ErrorViewResolver {

    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        //model对象原型为java.util.Collections$UnmodifiableMap无法修改
        Map<String , Object> result = Maps.newHashMap(model);
        Object exception = request.getAttribute("javax.servlet.error.exception");
        if (exception instanceof Exception) {
            String stackTrace = ExceptionUtils.getStackTrace((Throwable) exception);
            result.put("stackTrace" , stackTrace);
        }
        //状态码4xx的错误页面
        if (status.is4xxClientError()) {
            return new ModelAndView("/frame/4xx" , result , status);
        } else if (status.is5xxServerError()) {
            return new ModelAndView("/frame/5xx" , result , status);
        }
        return null;
    }
}

3.2 4xx页面编写

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8" />
    <title th:text="${status}">4xx页面</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
    <h2>4xx页面</h2>
    <h3>状态码:<th:block th:text="${status}"></th:block></h3>
    <h3>错误信息:<th:block th:text="${error}"></th:block></h3>
    <h3>页面地址:<th:block th:text="${path}"></th:block></h3>
    <h3>操作时间:<th:block th:text="${#dates.format(timestamp , 'yyyy年MM月dd日 HH时mm分ss秒')}"></th:block></h3>
</body>
</html>

3.3 5xx页面编写

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8" />
    <title th:text="${status}">5xx页面</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
    <h2>5xx页面</h2>
    <h3>状态码:<th:block th:text="${status}"></th:block></h3>
    <h3>错误信息:<th:block th:text="${error}"></th:block></h3>
    <h3>页面地址:<th:block th:text="${path}"></th:block></h3>
    <h3>操作时间:<th:block th:text="${#dates.format(timestamp , 'yyyy年MM月dd日 HH时mm分ss秒')}"></th:block></h3>
    <h3>异常堆栈:<th:block th:text="${stackTrace}"></th:block></h3>
</body>
</html>

3.4 运行结果

image.png

(自定义404页面显示)

image.png

(自定义500页面显示)

知识点说明

(1)需要实现ErrorViewResolver接口进行试图显示层的逻辑处理;

(2)可结合status状态和model参数变量进行页面按需展示;

(3)内置的参数有:状态码status;错误简述error;页面路径path;操作时间timestamp,若想输出异常堆栈则需要自行获取异常对账并设置至model中,如上述代码中的stackTrace处理;

(4)本站的页面异常处理使用Bootstrap主题的页面展示,提示友好;

源码下载

源码工程下载可转至https://gitee.com/88911006/chendd-blog-examples项目的ErrorPage分支;


 点赞


 发表评论

当前回复:作者

 评论列表


留言区