轻松解决SpringBoot的统一异常处理

怕什么真理无穷,进一寸,有进一寸的欢喜。

前言

关于如何搭建SpringBoot工程以及开启Web功能,
可以查看我的这篇博客:用Spring Initializr快速构建SpringBoot及整合MVC

异常分类

人不是上帝,无法写出不出错的程序;人也不是机器,我们不可能穷尽所有的异常一一分类处理,所以这个时候一个统一异常处理显得尤为重要。我们姑且把SpringBoot的异常按下图进行分类,然后一一进行处理。毕竟统一异常处理,也不是所有的异常都只做一个处理。
在这里插入图片描述
其中代码异常顾名思义就是当用户访问我们编写的代码所出现的异常,可分为同步请求和异步请求两类:同步请求一般如表单提交、超链接这类会跳转页面的请求;而异步请求主要为ajax异步请求,一般只会局部刷新页面。系统异常可以理解为不经过开发者自己编写代码所出现的异常。一般最常见的代码异常为404即找不到页面,比如我们开发b站随意在b站的根目录下输入一个网址,如点击进入b站404页面,我们可以发现b站的404页面竟然是可以看漫画的:
在这里插入图片描述

异常处理

代码异常

通过之前的解释我们可以知道,代码异常可分为同步请求异步请求,那么如何区分同步请求和异步请求呢?

我们可以分别写两个同步同步请求和异步请求,然后在浏览器检查元素,打开Network查看一下不同的请求:

同步请求:
在这里插入图片描述
异步请求:
在这里插入图片描述
那么有什么区别呢?仔细观察可以发现,异步请求似乎多了点东西:
在这里插入图片描述
对,就是这个:X-Requested-With: XMLHttpRequest,而仔细回想一下js创建ajax似乎是这么写:var xhr=new XMLHttpRequest();

代码实现

经过上述分析,也就不难理解下述代码:

package com.guqueyue.exception;

/**
 * @author guqueyue
 * @Date 2020/5/21
 * 代码异常处理
 **/
@ControllerAdvice
public class CommonsExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object exceptionHandler(HttpServletRequest request, Exception e) {
        System.out.println("出错啦:" + e.getMessage());
        String header = request.getHeader("X-Requested-With");
        // 判断是同步请求还是ajax请求
        if (header != null && header.equals("XMLHttpRequest")) {

            return new ResultData<>().setCode(ResultData.ResultCodeList.ERROR).setMessage("服务器繁忙,请稍后再试!");
        } else {
            return new ModelAndView("error/sorry");
        }

    }
}

当然,返回异步请求之前需要先有一个响应类:

/**
 * @author guqueyue
 * @Date 2020/4/25
 * 响应信息实体类
 **/
@Data //lombok插件的注解,若是没有用lombok插件,请自行生成getter、setter方法
@AllArgsConstructor //全参构造方法
@NoArgsConstructor //无参构造方法
@Accessors(chain = true) // 开启链式编程
public class ResultData<T> {

    /**
     * 响应码
     */
    private String code;

    /**
     * 响应信息
     */
    private String message;
    
    /**
     * 数据部分
     */
    private T data;

    /**
     * 响应的状态码列表
     */
    public static interface ResultCodeList {
        String OK = "200";
        String ERROR = "500";
    }
}

实现效果

经过上述请求,当我们的同步请求出现异常时,会自动显示错误页面(当然,上文中位于templates/error目录下的sorry页面需要自己编写):
在这里插入图片描述
当我们的ajax异步请求出现异常时,会自动提示错误信息(当然,弹窗提示错误信息需要自己在前端处理):
在这里插入图片描述

系统异常

在我们没有做系统异常处理之前,在项目根路径下随机访问一个不存在路径,会这样:
在这里插入图片描述
我们会发现当出现系统异常时,程序会自动访问/error路径,所以也就不难理解下面的代码:

package com.guqueyue.exception;

/**
 * @author guqueyue
 * @Date 2020/5/21
 * 系统异常处理,如404
 **/
@Controller
public class SystemExceptionHandler implements ErrorController {

    @RequestMapping("/error")
    public String systemException(HttpServletResponse response) {

        // 获得响应的状态码
        int status = response.getStatus();

        switch (status) {
            case 404:
                return "error/404";
        }

        return "error/sorry";
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }
}

这样当用户试图访问一个不存在的路径时,系统将会自动访问位于目录templates/error下的404.html文件,如:
在这里插入图片描述
当然,这个是我自己写的404页面。

  • 10
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值