Springboot对Controller层方法进行统一异常处理
Posted 南望孤笑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springboot对Controller层方法进行统一异常处理相关的知识,希望对你有一定的参考价值。
Controller层方法,进行统一异常处理
提供两种不同的方案,如下:
- 方案1:使用 @@ControllerAdvice (或@RestControllerAdvice), @ExceptionHandler 注解实现;
- 方案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; } }
以上是关于Springboot对Controller层方法进行统一异常处理的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot中在除Controller层 使用Validation的方式
SpringBoot框架中的DAO层Entity层Service层Controller层