springboot之全局异常处理和统一响应对象

一、springboot异常处理

1.SpringBoot 默认的异常处理机制

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

  1. 一种是浏览器客户端请求一个不存在的页面或服务端异常时,SpringBoot默认会响应一个html

    springboot之全局异常处理和统一响应对象_第1张图片

  2. 另一种是使用postman等调试工具请求不存在的url或服务端异常时,默认返回json信息

    springboot之全局异常处理和统一响应对象_第2张图片

2.SpringBoot 全局异常处理

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

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

2.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 "发生了未知异常";
       }
   }

springboot之全局异常处理和统一响应对象_第3张图片

2.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 "发生了未知异常";
    //}
}

springboot之全局异常处理和统一响应对象_第4张图片

全局异常注解已生效

3. 自定义异常

自定义异常只需要继承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, "自定义异常");
    }
}

二、统一响应对象

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

1.定义统一的响应对象

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

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

@Data
@NoArgsConstructor
@AllArgsConstructor
public class R {
    /**
     * 返回状态码
     */
    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.枚举信息

枚举一些常用的状态信息

我就举个例子,只枚举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;
    }
}

3.响应对象

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

@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());
    }
}

最后

一直想整理出一份完美的面试宝典,但是时间上一直腾不开,这套一千多道面试题宝典,结合今年金三银四各种大厂面试题,以及 GitHub 上 star 数超 30K+ 的文档整理出来的,我上传以后,毫无意外的短短半个小时点赞量就达到了 13k,说实话还是有点不可思议的。

需要完整版的小伙伴,可以一键三连后,点击这里!

一千道互联网 Java 工程师面试题

内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、SpringBoot、SpringCloud、RabbitMQ、Kafka、Linux等技术栈(485页)

《Java核心知识点合集(283页)》

内容涵盖:Java基础、JVM、高并发、多线程、分布式、设计模式、Spring全家桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat、数据库、云计算等

《Java中高级核心知识点合集(524页)》

《Java高级架构知识点整理》

 

 由于篇幅限制,详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

需要完整版的小伙伴,可以一键三连后,点击这里!

你可能感兴趣的:(java,全局异常,spring,boot,响应对象)