zoukankan      html  css  js  c++  java
  • 【异常处理】Springboot对Controller层方法进行统一异常处理

    Controller层方法,进行统一异常处理

    提供两种不同的方案,如下:

    1. 方案1:使用 @@ControllerAdvice (或@RestControllerAdvice), @ExceptionHandler 注解实现;
    2. 方案2: 使用AOP技术实现;

    现在分别介绍


    方案1: 使用@ControllerAdvice 和 @ExceptionHandler

    @ControllerAdvice 或 @RestControllerAdvice

    使用@ControllerAdvice注解来增强所有的 @RequestMapping标记的方法;

    官方解释:
    It is typically used to define @ExceptionHandler ,@InitBinder, and @ModelAttribute methods that apply to all @RequestMapping methods.

    @ExceptionHandler

    • 只能声明方法;
    • @ControllerAdvice结合使用,可以用于增强所有 @RequestMapping方法的异常处理;

    核心代码

    完整代码请参考: Springboot对Controller层方法进行统一异常处理

    @RestControllerAdvice
    public class ControllerExceptionHandleAdvice {
        private final static Logger logger = LoggerFactory.getLogger(ControllerExceptionHandleAdvice.class);
    
        @ExceptionHandler
        public ResultEntity handler(HttpServletRequest req, HttpServletResponse res, Exception e) {
            logger.info("Restful Http请求发生异常...");
    
            if (res.getStatus() == HttpStatus.BAD_REQUEST.value()) {
                logger.info("修改返回状态值为200");
                res.setStatus(HttpStatus.OK.value());
            }
    
            if (e instanceof NullPointerException) {
                logger.error("代码00:" + e.getMessage(), e);
                return ResultEntity.fail("发生空指针异常");
            } else if (e instanceof IllegalArgumentException) {
                logger.error("代码01:" + e.getMessage(), e);
                return ResultEntity.fail("请求参数类型不匹配");
            } else if (e instanceof SQLException) {
                logger.error("代码02:" + e.getMessage(), e);
                return ResultEntity.fail("数据库访问异常");
            } else {
                logger.error("代码99:" + e.getMessage(), e);
                return ResultEntity.fail("服务器代码发生异常,请联系管理员");
            }
        }
    }
    

    方案2:使用AOP技术

    完整代码: 【AOP】Springboot对Controller层方法进行统一异常处理

    核心代码

    • @Aspect 注解;
    • 织入点:
      • 方法返回值为:ResultEntity
      • 所有带有controller层级的包 下面的 所有类的所有方法
      • @Around("execution(public com.ssslinppp.model.ResultEntity com...controller...*(..))")
    @Component
    @Aspect
    public class ControllerAspect {
        public static final Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
    
        @Around("execution(public com.ssslinppp.model.ResultEntity com..*.controller..*.*(..))")
        public Object handleControllerMethod(ProceedingJoinPoint pjp) {
            Stopwatch stopwatch = Stopwatch.createStarted();
    
            ResultEntity<?> resultEntity;
            try {
                logger.info("执行Controller开始: " + pjp.getSignature() + " 参数:" + Lists.newArrayList(pjp.getArgs()).toString());
                resultEntity = (ResultEntity<?>) pjp.proceed(pjp.getArgs());
                logger.info("执行Controller结束: " + pjp.getSignature() + ", 返回值:" + resultEntity.toString());
                logger.info("耗时:" + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "(毫秒).");
            } catch (Throwable throwable) {
                resultEntity = handlerException(pjp, throwable);
            }
    
            return resultEntity;
        }
    
        private ResultEntity<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
            ResultEntity<?> resultEntity = null;
            if (e instanceof RuntimeException) {
                logger.error("RuntimeException{方法:" + pjp.getSignature() + ", 参数:" + pjp.getArgs() + ",异常:" + e.getMessage() + "}", e);
                resultEntity = ResultEntity.fail(e.getMessage());
            } else {
                logger.error("异常{方法:" + pjp.getSignature() + ", 参数:" + pjp.getArgs() + ",异常:" + e.getMessage() + "}", e);
                resultEntity = ResultEntity.fail(e.getMessage());
            }
    
            return resultEntity;
        }
    }
    
  • 相关阅读:
    Spring中的JDBC API
    Spring中的AOP(二)
    Nginx服务器代理静态资源
    Intellij IDEA配置Maven(内置Maven和修改本地仓库地址和阿里云中央仓库)
    Java函数传参(String的不可变性)
    Java中的前向引用与类初始化顺序
    【解决】com.mysql.cj.jdbc.Driver failed to unregister it /Abandoned connection cleanup thread
    SSM框架项目结构以及版本匹配
    Web4.0中web.xml头信息
    【解决】org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]
  • 原文地址:https://www.cnblogs.com/ssslinppp/p/7606038.html
Copyright © 2011-2022 走看看