全局异常处理器

531 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1、当我们重复向数据库中添加一条 设置了唯一约束的实体时候,会触发唯一异常

image.png

image.png 出现上述的错误, 主要就是因为在 employee 表结构中,我们针对于username字段,建立了唯一索引,添加重复的username数据时,违背该约束,就会报错。但是此时前端提示的信息并不具体,用户并不知道是因为什么原因造成的该异常,我们需要给用户提示详细的错误信息 。 image.png

2、虽然在我们服务端后台中可以看到这个异常,但是前端的用户,并不知道这个添加失败的原因。

2.6 全局异常处理

2.6.1 思路分析

要想解决上述测试中存在的问题,我们需要对程序中可能出现的异常进行捕获,通常有两种处理方式:

A. 在Controller方法中加入 try...catch 进行异常捕获

形式如下:

image.png

如果采用这种方式,虽然可以解决,但是存在弊端,需要我们在保存其他业务数据时,也需要在Controller方法中加上try...catch进行处理,代码冗余,不通用。

B. 使用异常处理器进行全局异常捕获

采用这种方式来实现,我们只需要在项目中定义一个通用的全局异常处理器,就可以解决本项目的所有异常。

2.6.2 全局异常处理器

在项目中自定义一个全局异常处理器,在异常处理器上加上注解 @ControllerAdvice,可以通过属性annotations指定拦截哪一类的Controller方法。 并在异常处理器的方法上加上注解 @ExceptionHandler 来指定拦截的是那一类型的异常。

异常处理方法逻辑:

  • 指定捕获的异常类型为 SQLIntegrityConstraintViolationException
  • 解析异常的提示信息, 获取出是那个值违背了唯一约束
  • 组装错误信息并返回

image.png

所属包: com.ligong.reggie.common

package com.ligong.reggie.common;
​
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
​
import java.sql.SQLIntegrityConstraintViolationException;
​
/**
 * 全局异常处理
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
​
    /**
     * 异常处理方法
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> handlerSqlException(SQLIntegrityConstraintViolationException ex) {
        String message = ex.getMessage();
        if (message.contains("Duplicate entry")) {
            String username = message.split(" ")[2];
            return R.error(username + "已存在");
        }
        return R.error("未知错误");
    }
​
}
​

注解说明:

上述的全局异常处理器上使用了的两个注解 @ControllerAdvice , @ResponseBody , 他们的作用分别为:

@ControllerAdvice : 指定拦截那些类型的控制器;

@ResponseBody: 将方法的返回值 R 对象转换为json格式的数据, 响应给页面;

上述使用的两个注解, 也可以合并成为一个注解 @RestControllerAdvice

image.png