springboot 全局异常处理和统一响应对象的处理方式


Posted in Java/Android onJune 28, 2022

springboot异常处理

SpringBoot 默认的异常处理机制

默认情况,SpringBoot 提供两种不同响应方式

  • 一种是浏览器客户端请求一个不存在的页面或服务端异常时,SpringBoot默认会响应一个html
  • 另一种是使用postman等调试工具请求不存在的url或服务端异常时,默认返回json信息

SpringBoot 全局异常处理

一般我们不会将错误信息返回前端,自己去try catch捕获异常,但有个问题:每个方法都这样捕获异常,肯定是不合适,这是我们就需要全局的异常处理了。

@RestController
public class ExceptionController {
    @GetMapping("exceptionA")
    public void methodA() {
        try {
            int a = 100 / 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1. 局部异常处理

使用@EceptionHandle注解实现某个类的局部异常处理

@RestController
   public class ExceptionController {
   
       @GetMapping("exceptionA")
       public void methodA() {
           int a = 100 / 0;
       }
   
       /**
        * 局部异常处理
        */
       @ExceptionHandler(Exception.class)
       public String exHandler(Exception e) {
           // 判断发生异常的类型是除0异常则做出响应
           if (e instanceof ArithmeticException) {
               return "发生了除0异常";
           }
           // 未知的异常做出响应
           return "发生了未知异常";
       }
   }

2. 全局异常处理

使用@ControllerAdvice +@ExceptionHandler注解实现全局异常处理

自定义一个异常类

@RestControllerAdvice
public class DefaultException {
​
    @ExceptionHandler({NullPointerException.class})
    public String exception(NullPointerException exception) {
        return "空指针异常";
​
    }
​
    @ExceptionHandler({IndexOutOfBoundsException.class})
    public String exception(IndexOutOfBoundsException exception) {
        return "数组越界异常";
    }
}

增加一个异常方法测试,由于局部异常优先级更高先注释掉了

@RestController
public class ExceptionController {
​
    @GetMapping("exceptionA")
    public void methodA() {
        int a = 100 / 0;
    }
​
    @GetMapping("exceptionB")
    public void methodB() {
        List list = new ArrayList<>();
        System.out.println(list.get(0));
    }
​
    /**
     * 局部异常处理
     */
    //@ExceptionHandler(Exception.class)
    //public String exHandler(Exception e) {
    //    // 判断发生异常的类型是除0异常则做出响应
    //    if (e instanceof ArithmeticException) {
    //        return "发生了除0异常";
    //    }
    //    // 未知的异常做出响应
    //    return "发生了未知异常";
    //}
}

全局异常注解已生效

自定义异常

自定义异常只需要继承exception类或其子类

@Data
@NoArgsConstructor
public class CustomException extends Exception {
​
    private static final long serialVersionUID = 1L;
​
    private Integer code;
​
    private String mes;
​
    /**
     * @param code 状态码
     * @param msg  异常返回信息
     * @description 构造器
     */
    public CustomException(Integer code, String msg) {
        super(msg);
        this.code = code;
    }
}

使用时可以直接抛出异常对象

@GetMapping("exceptionC")
public void methodC() throws CustomException {
    int a = 1;
    if (a == 1) {
        throw new CustomException(10086, "自定义异常");
    }
}

统一响应对象

实际开发中我们需要封装统一的响应对象,区分状态码和信息,以便前端处理。

定义统一的响应对象

一般包含状态码,错误信息,数据等。

自定义一些方法用来返回信息,比如我定义的success(),failed()方法

@Data
@NoArgsConstructor
@AllArgsConstructor
public class R<T> {
    /**
     * 返回状态码
     */
    private Integer code;
    /**
     * 返回信息
     */
    private String msg;
    /**
     * 数据
     */
    private T data;
​
    public static R success() {
        return new R(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), null);
    }
​
    public static R success(Object data) {
        return new R(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), data);
    }
​
    public static R failed() {
        return new R(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMsg(), null);
    }
​
    public static R failed(String msg) {
        return new R(ResultCode.FAILED.getCode(), msg, null);
    }
​
    public static R failed(int code, String msg) {
        return new R(code, msg, null);
    }
}

枚举信息

枚举一些常用的状态信息

我就举个例子,只枚举2个,根据需要去自定义

@NoArgsConstructor
@AllArgsConstructor
public enum ResultCode {
​
    SUCCESS(200, "请求成功"),
    FAILED(500, "服务器错误");
​
    private int code;
    private String msg;
​
    public int getCode() {
        return code;
    }
​
    public void setCode(int code) {
        this.code = code;
    }
​
    public String getMsg() {
        return msg;
    }
​
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

响应对象

使用时直接返回定义的对象类型就行了,将定义的全局异常返回类型也改成统一的响应对象

@RestControllerAdvice
public class DefaultException {
    @ExceptionHandler({CustomException.class})
    public R exception(CustomException e) {
        return R.failed(e.getCode(),e.getMessage());
    }

    @ExceptionHandler({Exception.class})
    public R exception(Exception e) {
        return R.failed(e.getMessage());
    }
}

全局异常和响应对象的简单介绍就这样了,欢迎补充指正。

gitee地址:gitee.com/rainscloud/…

到此这篇关于springboot 全局异常处理和统一响应对象的文章就介绍到这了,更多相关springboot全局异常处理内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

Java/Android 相关文章推荐
Spring Boot 整合 Apache Dubbo的示例代码
Jul 04 Java/Android
小程序与后端Java接口交互实现HelloWorld入门
Jul 09 Java/Android
mybatis 获取无数据的字段不显示的问题
Jul 15 Java/Android
JavaWeb 入门:Hello Servlet
Jul 16 Java/Android
JavaWeb 入门篇(3)ServletContext 详解 具体应用
Jul 16 Java/Android
gateway与spring-boot-starter-web冲突问题的解决
Jul 16 Java/Android
Java字符串逆序方法详情
Mar 21 Java/Android
零基础学java之带参数以及返回值的方法
Apr 10 Java/Android
Android开发实现极为简单的QQ登录页面
Apr 24 Java/Android
MyBatis核心源码深度剖析SQL语句执行过程
May 20 Java/Android
SpringBoot使用AOP实现统计全局接口访问次数详解
Jun 16 Java/Android
详解Spring Security如何在权限中使用通配符
Jun 28 Java/Android
详解Spring Security如何在权限中使用通配符
Jun 28 #Java/Android
Android RecyclerView实现九宫格效果
Jun 28 #Java/Android
Java 多线程并发FutureTask
Java+swing实现抖音上的表白程序详解
Jun 25 #Java/Android
Java Spring Boot请求方式与请求映射过程分析
Jun 25 #Java/Android
Spring Cloud OAuth2实现自定义token返回格式
Jun 25 #Java/Android
Spring Cloud OpenFeign模版化客户端
Jun 25 #Java/Android
You might like
php下将多个数组合并成一个数组的方法与实例代码
2011/02/03 PHP
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
2012/12/10 PHP
PHP命名空间(Namespace)的使用详解
2013/05/04 PHP
php把session写入数据库示例
2014/02/26 PHP
从PHP的源码中深入了解stdClass类
2014/04/18 PHP
不用写JS也能使用EXTJS视频演示
2008/12/29 Javascript
html超链接打开窗口大小的方法
2013/03/05 Javascript
FF IE浏览器修改标签透明度的方法
2014/01/27 Javascript
vue中用动态组件实现选项卡切换效果
2017/03/25 Javascript
vue监听滚动事件实现滚动监听
2017/04/11 Javascript
JS实现点击循环切换显示内容的方法
2017/10/19 Javascript
详解Angular调试技巧之报错404(not found)
2018/01/31 Javascript
js实现类选择器和name属性选择器的示例步骤
2021/02/07 Javascript
[01:45]DOTA2新英雄“神谕者”全方位展示
2014/11/21 DOTA
[01:39:42]Fnatic vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python返回真假值(True or False)小技巧
2015/04/10 Python
python实现自动登录人人网并采集信息的方法
2015/06/28 Python
python requests爬取高德地图数据的实例
2018/11/10 Python
python如何实现异步调用函数执行
2019/07/08 Python
Python中一个for循环循环多个变量的示例
2019/07/16 Python
python实现图片九宫格分割
2021/03/07 Python
Django Rest framework权限的详细用法
2019/07/25 Python
HTML5 Canvas渐进填充与透明实现图像的Mask效果
2013/07/11 HTML / CSS
CHARLES & KEITH加拿大官网:新加坡时尚品牌
2020/03/26 全球购物
Bloomingdale’s阿联酋:选购奢华时尚、美容及更多
2020/09/22 全球购物
SQL面试题
2013/12/09 面试题
提高EJB性能都有哪些技巧
2012/03/25 面试题
仓库主管的岗位职责
2013/12/04 职场文书
诉讼财产保全担保书
2014/05/20 职场文书
销售员工作检讨书(推荐篇)
2014/10/18 职场文书
2014年幼儿园后勤工作总结
2014/11/10 职场文书
公司庆典欢迎词
2015/01/26 职场文书
催款函怎么写
2015/06/24 职场文书
CocosCreator入门教程之网络通信
2021/04/16 Javascript
Ajax常用封装库——Axios的使用
2021/05/08 Javascript
Mysql表数据比较大情况下修改添加字段的方法实例
2022/06/28 MySQL