SpringBoot异常处理机制

0 阅读2分钟

介绍

在一个复杂而又庞大的项目中分开处理可能出现的异常显然不现实,SpringBoot就为我们提供了一套优雅的解决方案--全局异常处理器。借助全局异常处理器可以统一处理项目运行时可能出现的异常

实现

/**  
 * 全局异常处理器,处理项目中抛出的业务异常  
 */  
@RestControllerAdvice  
@Slf4j  
public class GlobalExceptionHandler {  
  
    /**  
     * 捕获业务异常  
     * @param ex  
     * @return  
     */    
    @ExceptionHandler  
    public Result exceptionHandler(Exception ex){  
        log.error("异常信息:{}", ex.getMessage());  
        return Result.error(ex.getMessage());  
    }  
 
}

解读

注解:

  • @RestControllerAdvice:Spring MVC的全局异常处理注解,会自动捕获所有Controller层抛出的异常。
  • @ExceptionHandler:当 Controller 层抛出异常时,Spring 会自动寻找带有该注解的方法来处理。
  • @Slf4j:Lombok提供的日志注解,用于记录异常信息。

综上,异常被捕获到后会寻找带有@ExceptionHandler注解,且形参中的异常是该异常或其父类的方法,并进入方法体乖乖地等待你的处理~

实践

来看下面的方法如何实现处理数据库违反唯一约束(字段重复)的异常,并友好地返回异常提示。

    /**  
     * 捕获SQL异常  
     * @param ex  
     * @return  
     */    
    @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 + "已存在";  
            return Result.error(msg);  
        } else {  
            return Result.error(MessageConstant.UNKNOWN_ERROR);  
        }  
    }  
  1. 拿到完整报错信息message,形如Duplicate entry 'value' for key 'key_name'。
  2. 二次确认异常类型,如果message中包含了Duplicate entry,那确实是我们期望处理的异常。
  3. 处理原始信息,拿到违反了唯一约束的值,并得到最终返回的msg。
  4. 给前端返回错误信息,例如在输入用户名时弹出”张三已存在“。

注意! Spring按异常类型的继承关系匹配最具体的处理器,但如果方法参数过于宽泛(如Exception),可能拦截了本该由更具体方法处理的异常。 因此,建议处理异常方法的形参越具体越好