Springboot全局异常处理


为什么使用全局异常?

  • 在开发过程中,不管是 Dao、Servie、Controller,层都有可能发生异常,对于异常处理,通常是 try-catch 或者直接 throw,这会让 try-catch 的代码在代码中任意出现,系统的代码耦合度高,代码不美观,统一异常处理可以美化代码。

如何使用全局异常?

  • 在后端处理请求过程中发生了异常,DispatcherServlet 将异常处理委托给异常处理器(处理异常的类)。实现 HandlerExceptionResolver 接口的都是异常处理类。
  • 项目的异常一般集中处理,定义全局异常处理器。再结合框架提供的注解,诸如:@ExceptionHandler@ControllerAdvice@RestControllerAdvice 一起完成异常的处理。注意: 一定要和Controller中的注解(@Controller 和 RestController)保持一致性。
  • @ControllerAdvice@RestControllerAdvice 区别在于:@RestControllerAdvice 加了@RepsonseBody

一、不使用全局异常处理器

  • ① 编写控制器相关的代码,模拟出现了空指针异常。NullPointerException

    @RestController
    public class Controller {
    
        @GetMapping("/divide")
        public String divide(){
            String str = null;
            str.toString();
            return "success";
        }
    }
    
  • ② 发送请求返回结果查看。
    在这里插入图片描述


二、全局异常处理器

  • SpringBoot中,@ControllerAdvice 或 @RestControllerAdvice 即可开启全局异常处理,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用@ExceptionHandler注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。

1.自定义常量(返回状态码)

/**
 * 返回状态码的常量
 **/
public class StatusCodeConstant {
    public static final Integer ERROR = 500; //服务器非法错误
}

2.手动抛出异常

@RestController
public class Controller {
    @GetMapping("/divide")
    public String divide(){
        String str = null;
        str.toString();
        return "success";
    }
}

3.编写全局异常处理器

    /**
     * 处理空指针的异常
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public String exceptionHandler(NullPointerException e){
        return "<h1>服务器出现错误,请联系管理员 ====> " + e.getMessage() + "</h1>";
    }

4.测试结果

在这里插入图片描述

  • 建议在参数签名中尽可能具体异常类,以减少异常类型和原因异常之间不匹配的问题,考虑创建多个@ExceptionHandler 方法的,每个方法通过其签名匹配单个特定的异常类型。最后增加一个根异常,考虑没有匹配的其他情况。

三、全局异常处理方式二

1.定义状态码常量

public class StatusCodeConstant {
    public static final Integer SUCCESS = 200;  //返回状态正常
    public static final Integer ERROR = 0; //返回错误
}

2. 定义基础接口(面向接口编程)

/**
 * 响应信息的基础接口
 **/
public interface ResponseResultBaseInfo {
    /**
     *  错误码
     */
    Integer getResultCode();

    /**
     * 错误描述
     */
    String getResultMsg();
}

3.定义枚举类

/**
 * 异常处理枚举类
 */
public enum ResponseEnum implements ResponseResultBaseInfo{

    // 数据操作错误定义
    SUCCESS(200, "success"),
    ERROR(500,"error");

    /**
     * 错误码
     */
    private final Integer resultCode;

    /**
     * 错误描述
     */
    private final String resultMsg;

    ResponseEnum(Integer resultCode, String resultMsg) {
        this.resultCode = resultCode;
        this.resultMsg = resultMsg;
    }

    @Override
    public Integer getResultCode() {
        return resultCode;
    }

    @Override
    public String getResultMsg() {
        return resultMsg;
    }
}

4.自定义数据传输对象

/**
 * 自定义数据传输对象
 */
@Data
public class ResponseResult {
    /**
     * 响应代码
     */
    private Integer code;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应结果
     */
    private Object result;
    public ResponseResult(){

    }

    public ResponseResult(ResponseResultBaseInfo res) {
        this.code = res.getResultCode();
        this.message = res.getResultMsg();
    }

    /**
     * 成功
     */
    public static ResponseResult success() {
        return success(null);
    }

    /**
     * 成功
     */
    public static ResponseResult success(Object data) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(ResponseEnum.SUCCESS.getResultCode());
        responseResult.setMessage(ResponseEnum.SUCCESS.getResultMsg());
        responseResult.setResult(data);
        return responseResult;
    }

    /**
     * 失败
     */
    public static ResponseResult error(ResponseResultBaseInfo res) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(res.getResultCode());
        responseResult.setMessage(res.getResultMsg());
        responseResult.setResult(null);
        return responseResult;
    }

    /**
     * 失败
     */
    public static ResponseResult error(Integer code, String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(code);
        responseResult.setMessage(message);
        responseResult.setResult(null);
        return responseResult;
    }

    /**
     * 失败
     */
    public static ResponseResult error(String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(StatusCodeConstant.ERROR);
        responseResult.setMessage(message);
        responseResult.setResult(null);
        return responseResult;
    }

}

5.定义全局异常处理器

/**
 * 全局异常处理器
 **/
@RestControllerAdvice 
public class ExceptionHandlerConfig {
    @ExceptionHandler(NullPointerException.class)
    public ResponseResult nullPointException(NullPointerException e) {
        return ResponseResult.error(e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ResponseResult exception() {
        return ResponseResult.error(ResponseEnum.ERROR);
    }
}

6.测试1

    @GetMapping("/latest")
    public ResponseResult getSensorDataLatest() {
        return ResponseResult.success("数据传输成功");
    }

在这里插入图片描述

7.测试2

    @GetMapping("/latest")
    public ResponseResult getSensorDataLatest() {
        int a = 1;
        if(a == 1)
            throw new ArithmeticException();
        return ResponseResult.success("数据传输成功");
    }

在这里插入图片描述


四、值得参考的博客


相关推荐

  1. SpringBoot全局异常处理

    2024-03-17 16:54:01       28 阅读
  2. Springboot全局异常处理

    2024-03-17 16:54:01       30 阅读
  3. SpringBoot全局异常处理方法

    2024-03-17 16:54:01       19 阅读
  4. springboot全局处理sql异常

    2024-03-17 16:54:01       6 阅读
  5. Springboot自定义全局异常处理

    2024-03-17 16:54:01       32 阅读
  6. Springboot整合hibernate validator 全局异常处理

    2024-03-17 16:54:01       30 阅读
  7. springboot全局异常处理和自定义异常处理

    2024-03-17 16:54:01       40 阅读
  8. SpringBoot实现自定义异常+全局异常统一处理

    2024-03-17 16:54:01       36 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-17 16:54:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-17 16:54:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-17 16:54:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-17 16:54:01       18 阅读

热门阅读

  1. uniapp 实现双击点赞出现特效

    2024-03-17 16:54:01       24 阅读
  2. MongoDB

    MongoDB

    2024-03-17 16:54:01      18 阅读
  3. 栈与队列|239.滑动窗口最大值 (单调队列)

    2024-03-17 16:54:01       19 阅读
  4. 基于AI的测试优化方法

    2024-03-17 16:54:01       20 阅读
  5. 【C++】通讯录管理系统

    2024-03-17 16:54:01       19 阅读
  6. 【Python】实现一个鼠标连点器

    2024-03-17 16:54:01       20 阅读
  7. OGR2GUI

    OGR2GUI

    2024-03-17 16:54:01      18 阅读
  8. Hive调优总结

    2024-03-17 16:54:01       20 阅读
  9. 作业1:计算机体系结构导论

    2024-03-17 16:54:01       17 阅读
  10. 文档解析应该获取哪些知识?

    2024-03-17 16:54:01       20 阅读
  11. godot shader参考

    2024-03-17 16:54:01       21 阅读