全局异常处理

空~2022年11月12日大约 1 分钟

全局异常处理

为集中处理系统异常,自定义统一的错误码,并封装了全局异常处理器 ,屏蔽了项目冗余的报错细节、便于接口调用方理解和统一处理。

@ControllerAdvice 注解

ControllerAdvice 本质上是一个 Component

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice

Specialization of @Component for classes that declare @ExceptionHandler, @InitBinder, or @ModelAttribute methods to be shared across multiple @Controller classes.

设定拦截规则, 根据拦截规则进行拦截,通过@ExceptionHandler、@InitBinder 或 @ModelAttribute 这三个注解以及被其注解的方法来实现具体逻辑。

默认什么都不写,拦截所有 Controller

详细参数

@AliasFor("basePackages")
String[] value() default {};

@AliasFor("value")
String[] basePackages() default {};

Class<?>[] basePackageClasses() default {};

Class<?>[] assignableTypes() default {};

Class<? extends Annotation>[] annotations() default {};

@ControllerAdvice("org.my.pkg") @ControllerAdvice(basePackages="org.my.pkg") @ControllerAdvice(basePackages={"org.my.pkg", "org.my.other.pkg"}) 拦截对应包及其子包下所有的 Controller

也可以通过指定注解来匹配,比如我自定了一个 @CustomAnnotation 注解,我想匹配所有被这个注解修饰的 Controller, 可以这么写:@ControllerAdvice(annotations={CustomAnnotation.class})

/**
 * 全局异常处理
 */
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 异常处理方法
     *
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex) {
        log.error(ex.getMessage());

        if (ex.getMessage().contains("Duplicate entry")) {
            String[] split = ex.getMessage().split(" ");
            String msg = split[2] + "已存在";
            return R.error(msg);
        }
        return R.error("未知错误");
    }

     /**
     * 异常处理方法
     *
     * @return
     */
    @ExceptionHandler(CustomException.class)
    public R<String> exceptionHandler(CustomException ex) {
        log.error(ex.getMessage());

        return R.error(ex.getMessage());
    }
}