SpringBoot:全局异常处理器

💥 该系列属于【SpringBoot基础】专栏,如您需查看其他SpringBoot相关文章,请您点击左边的连接

目录

一、场景引入

1. 项目结构

2. Result

3. Controller

4. 接口测试

(1)errorTest

(2)exceptionTest

5. 异常处理方案

(1)方案一:try-catch

(2)方案二:全局异常处理器

二、全局异常处理器

1. 代码

2. 接口测试

3. 其他


一、场景引入

SpringBoot程序在运行时可能会遇到不可预知的异常,这些异常信息通常不遵循后端返回给前端的统一消息格式

下面来模拟一下这种异常的发生。

1. 项目结构

2. Result

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Result<T> implements Serializable {
    Integer code;
    String msg;
    T data;

    public static <T> Result<T> success() {
        Result<T> result = new Result<>();
        result.code = 1;
        return result;
    }

    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.code = 1;
        result.data = data;
        return result;
    }

    public static <T> Result<T> error(String msg) {
        Result<T> result = new Result<>();
        result.code = 0;
        result.msg = msg;
        return result;
    }

}

3. Controller

@RestController
public class TestController {
    @RequestMapping("/exceptionTest")
    public Result exceptionTest() {            //异常测试
        int i = 1 / 0;
        return Result.success();
    }

    @RequestMapping("/errorTest")
    public Result errorTest() {
        return Result.error("这是一个错误");    //错误测试
    }
}

exceptionTest这里是代表了服务器端程序运行时可能出现的异常,而实际开发中一些异常往往是不可预知的,这里仅仅用来模拟。

errorTest这里代表后端返回给前端的错误消息统一格式。

4. 接口测试

(1)errorTest

error返回格式遵循后端给前端的消息格式。

(2)exceptionTest

此时返回给前端的并不遵循消息格式,因此后端有必要全局捕获异常,以统一的格式返回给前端。

5. 异常处理方案

(1)方案一:try-catch

实际开发的三层架构中,Controller,Service,Mapper都可能抛出异常,由于三层架构的调用关系,最终会将异常返回给Controller。

此时可以在每个Controller的方法中都设置try-catch,如果这么做那么代码将变得非常臃肿,可阅读性也变差。因此这种方案并不可取。

(2)方案二:全局异常处理器

全局异常处理器是一种处理整个应用中抛出的异常的机制。其核心思想是集中管理异常处理逻辑,从而提供一种一致的方式来响应异常情况,而不是在每个controller方法中分别处理异常。

二、全局异常处理器

1. 代码

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public Result exceptionHandler(Exception ex) {    //处理一切异常Exception
        log.error("异常信息:{}", ex.getMessage());
        return Result.error(ex.getMessage());
    }
}

2. 接口测试

可以看出处理了异常,并按照统一格式返回给前端。

3. 其他

实际开发中,可以针对不同类型的异常进行分别处理。摘自黑马程序员《苍穹外卖》项目,代码示例如下:

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 捕获业务异常
     */
    @ExceptionHandler
    public Result exceptionHandler(BaseException ex){ //自定义BaseException用来处理业务异常
        log.error("异常信息:{}", ex.getMessage());
        return Result.error(ex.getMessage());
    }

    /**
     * 处理SQL异常
     */
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2];
            String msg = username + MessageConstant.ALREADY_EXISTS;
            return Result.error(msg);
        }else{
            return Result.error(MessageConstant.UNKNOWN_ERROR);
        }
    }
}

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值