背景:最近在开发过程中遇到了一个@ControllerAdvice注解不生效的bug,排查了一下,特此记录一下,希望大家不要想我一样犯这种低级错误;

@ControllerAdvice注解简单说明

@ControllerAdvice的实际上就是一个@Component,用于对Controller进行切面环绕处理,默认是全局,可配置。作用在类上的注解,其主要用法有三个:(主要用法就是对异常的处理)

  • 结合@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常(catch的异常不会触发哦),从而达到不同类型的异常区别处理的目的 (常用
  • 结合@InitBinder,用于request中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的
  • 结合@ModelAttribute,表示其注解的方法将会在目标Controller方法执行之前执行。

定义的ExceptionAdvice类

package com.central.manager.config;

import com.central.common.exception.DefaultExceptionAdvice;
import org.springframework.web.bind.annotation.ControllerAdvice;

/**
 * @author kiwi
 * @date 2022/08/30
 */
@ControllerAdvice
public class ExceptionAdvice extends DefaultExceptionAdvice {
}

######################分割线############################################

package com.central.common.exception;

import com.central.common.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.sql.SQLException;

/**
 * 异常通用处理
 *
 * @author kiwi
 */
@ResponseBody
@Slf4j
public class DefaultExceptionAdvice {
    /**
     * IllegalArgumentException异常处理返回json
     * 返回状态码:400
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({IllegalArgumentException.class})
    public Result badRequestException(IllegalArgumentException e) {
        return defHandler("参数解析失败", e);
    }

    /**
     * AccessDeniedException异常处理返回json
     * 返回状态码:403
     */
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ExceptionHandler({AccessDeniedException.class})
    public Result badMethodExpressException(AccessDeniedException e) {
        return defHandler("没有权限请求当前方法", e);
    }

    /**
     * 返回状态码:405
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public Result handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        return defHandler("不支持当前请求方法", e);
    }

    /**
     * 返回状态码:415
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    public Result handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
        return defHandler("不支持当前媒体类型", e);
    }

    /**
     * SQLException sql异常处理
     * 返回状态码:500
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({SQLException.class})
    public Result handleSQLException(SQLException e) {
        return defHandler("服务运行SQLException异常", e);
    }

    /**
     * BusinessException 业务异常处理
     * 返回状态码:500
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(BusinessException.class)
    public Result handleException(BusinessException e) {
        return defHandler("业务异常", e);
    }

    /**
     * IdempotencyException 幂等性异常
     * 返回状态码:200
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(IdempotencyException.class)
    public Result handleException(IdempotencyException e) {
        return Result.failed(e.getMessage());
    }

    /**
     * 所有异常统一处理
     * 返回状态码:500
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        return defHandler("未知异常", e);
    }

    /**
     *空指针异常
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(NullPointerException.class)
    public Result nullException(Exception e) {
        return defHandler("空指针异常", e);
    }
    private Result defHandler(String msg, Exception e) {
        log.error(msg, e);
        return Result.failed(msg);
    }
}

项目中也没有其他的Aspect类进行try操作,但就是不生效;
后面发现这个ExceptionAdvice没有被引用的高亮,后面就根据这个排查,发现是我的config包路径写错了地方
在这里插入图片描述
config和manager同级了,启动类肯定扫描不到这个包,自然也就不会生效

在这里插入图片描述

修改之后就可以正常的返回我们自己对异常的处理了
开发的过程中还是要避免这种低级吃错误,之前没发现这个高亮的问题,我一直找是不是哪里有try/catch处理,耽误了很多时间,特此记录

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐