SpringBoot统一异常处理

软件开发过程中有一大半的时间都是在处理各种异常情况,并且各种异常还防不胜防,稍有不慎就会有遗漏。导致代码中出现大量的try {...} catch {...} finally {...}代码块,不仅难易维护,并且也不优雅,会被其他接手同学背后喊骂,甚至自己都会觉得写的太烂了。这种情况SpringBoot框架当然也有想到,因此Spring3.2增加了@ControllerAdvice结合@ExceptionHandler进行全局异常处理,接下来将详细介绍全局统一异常处理的方法

Spring在3.2版本增加了@ControllerAdvice,可以与@ExceptionHandler、@InitBinder、@ModelAttribute等注解配套使用,对于异常处理使用@ExceptionHandler即可

直观的想法就是在每个Controller定义一套异常处理方法(由于每个Controller的异常有可能不一样,且数量众多),并在方法上增加@ExceptionHandler注解,当出现各种异常是,就可以使用该方法进行处理,这种方案想想都不优雅,需要每个Controller都处理,升级方法就是继承BaseController之类的,但是也不优雅,一个简单的Controller竟然需要继承,如果还有其他基类需要继承则该方案就行不通了。针对这种困惑,SpringBoot也想到了即是用@ControllerAdvice,该注解可以把异常处理器应用到所有的Controller而不是单个的,基于该注解(只需要在类签名增加该注解),可以单独定义一个异常处理类,在类中定义一套各种的异常处理机制,就可以统一对不同阶段、不同异常进行处理,避免重复的冗余代码,也避免遗漏一些异常,更避免了频繁修改代码。

@RestControllerAdvice + @ExceptionHandler 统一全局异常处理

本文介绍@RestControllerAdvice(=@ControllerAdvice + @ResponseBody) + @ExceptionHandler进行全局的Controller层异常处理,避免在Controller层进行大量的try-catch,而且可以结合@Validation注解校验器一起处理,无需手动判断绑定校验结果BindingResult/Errors

优缺点

优点:将Controller层的异常和数据校验的异常进行统一处理,减少模板代码,减少编码量,提升扩展性和可维护性
缺点:只能处理Controller层未捕获(往外抛)的异常,对于Interceptor(拦截器)层的异常,Spring框架层的异常,就无能为力了

使用实例

@RestControllerAdvice定义全局异常处理类

@RestControllerAdvice
public class GlobalExceptionHandler {
}

请确保GlobalExceptionHandler类能被扫描到并装载进Spring容器中

@ExceptionHandler注解声明异常处理方法

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public Object exceptionHandler(Exception e) {
        log.error(e.getMessage, e);
        return "Exception ..."; // 可以根据具体场景调整返回数据结构体
    }
}

该exceptionHandler会自动处理Controller层抛出的Exception及其子类的异常,参数Exception就是Controller抛出的异常

处理自定义异常

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(BusinessException.class)
    public Object exceptionHandler(BusinessException e) {
        log.error(e.getMessage, e);
        return "BusinessException ..."; // 可以根据具体场景调整返回数据结构体
    }
}

public class BusinessException extends RuntimeException {

    public BusinessException(String message) {
        super(message);
    }

    public BusinessException(String message, Throwable th) {
        super(message, th);
    }
}

参考

统一异常处理介绍及实战
使用@ControllerAdvice + @ExceptionHandler 全局处理Controller 层异常
Spring进阶之@ControllerAdvice与统一异常处理
优雅的处理你的Java异常

你可能感兴趣的:(SpringBoot统一异常处理)