@ControllerAdvice全局异常处理器不起作用了?看看我是怎么解决的

本文主要是介绍@ControllerAdvice全局异常处理器不起作用了?看看我是怎么解决的,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:最近项目中使用了@ControllerAdvice+@ExceptionHandler注解组合,实现全局异常处理器,处理代码中手动向上抛出的异常(throws和throw)和自动向上抛出的异常(默认),代码全局异常处理器代码本身写的没问题,但不知道为啥就是不起作用,下面看我怎么解决的吧!

前言:

我们都知道java中异常处理方式有两种

1、就地解决

用try-catch块包裹住容易发生异常的代码片段,这样当该代码片段真正发生异常后,就会立即被catch块捕捉并在catch块中处理,从而使代码继续往下执行,不影响其他代码的执行。

2、向上抛出

如果不想立马就地处理,可以选择将该异常向上抛出,让方法的调用者处理。若方法的调用者也不行处理,同样可以继续向上抛出该异常,以此类推,直到将该异常抛给JVM处理。可是JVM懒啊,一看你们该处理的都不处理是吧,好,我也不处理,我还要把你们方法的调用过程给晒出来,结果就可以在控制台看到方法调用的堆栈信息了。

1、为啥要使用全局异常处理器?

总是用try-catch块包裹代码块也不好,影响性能不说代码看着不是很美观,所以我们选择用第二种——向上抛出的方式。向上抛出没问题,但总要有一个地方处理该异常,在web系统当中还应该将该异常以一个用户可以接受的方式返回给前端,不但在接口对接的时候让前端小姐姐知道是我们后台接口出现了问题,不至于摸不着头脑;而且我们后端开发人员也能根据接口返回的结果快速的知道到底是哪里出现了问题,才能快速解决问题。

2、我的@RestControllerAdvice标注的全局异常处理器

先看下我的全局异常处理器写的没问题是吧:

@RestControllerAdvice //等于@ControllerAdvice+@ResponseBody,和@RestController一个道理
public class OaExpHandler {/*** 处理所有的异常和Throwable类* @param e* @return*/@ExceptionHandler({Exception.class,Throwable.class})public Map<String,Object> testExceptionHandler1(Exception e){System.out.println("进来了");Map<String, Object> map = new HashMap<>();map.put("code",400);map.put("msg","出错啦");return map;}
}  

很简单也没啥问题对吧,但是为啥不行呢?

3、无效的原因

网上有好多是说没有被扫描到,即没有纳入IOC容器中,这确实是一个原因,但我怎么会犯这个错误呢?

其实还有一个原因,@ControllerAdvice全局异常处理器是处理controller中向上抛出后没有被处理的异常,若异常在到达该异常处理器前就已经被处理了,自然就不会到达@ExceptionHandler标注的方法处理。我的就是这个原因...

我看了下controller中没有try-catch块,但是我有两个切面,对所有的controller方法进行了环绕通知——找到原因了啊。

一起看看罪魁祸首:

@Around("controllerPointcutExpress() || actControllerPointcutExpress()")public Object execTimeAround(ProceedingJoinPoint joinPoint) throws Throwable {Object result = null;long start = System.currentTimeMillis();/*try {result = joinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}*/result = joinPoint.proceed();//获取目标方法的全类名MethodSignature signature = (MethodSignature)joinPoint.getSignature();Method targetMethod = signature.getMethod();System.out.println("目标方法:"+targetMethod +"执行总时长为------- {"+(System.currentTimeMillis() - start)+"}毫秒");return result;}

被注释的代码就是那段有罪的代码,可以看到我用try-catch块对proceed()方法进行了包裹,所以一旦目标方法出现了异常,这里的catch块就会非常勤快的捕捉到异常并处理掉,自然没有向上抛出去,也就无法到达@ControllerAdvice标注的全局异常处理器中。看到这里不禁会问,嗯?难道Aspect切面的执行顺序在@ControllerAdvice之前?但是事实上就是这个样子的。

4、根本原因

一张图足以说明一切:

springMVC请求与响应中各组件的执行顺序

看完本篇文章只要能学到两点就可以了

1、理解java异常处理的机制。

2、知道filter、interceptor、controllerAdvice、Aspect、controller在springMVC中的执行顺序。

 

好了,今天就到这里吧,希望看完本篇文章能解决你的问题,若能学点东西就更好了。

另外,祝你每天开心、升职加薪、生活幸福!

 

 

 

 

这篇关于@ControllerAdvice全局异常处理器不起作用了?看看我是怎么解决的的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/502295

相关文章

Spring三级缓存解决循环依赖的解析过程

《Spring三级缓存解决循环依赖的解析过程》:本文主要介绍Spring三级缓存解决循环依赖的解析过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、循环依赖场景二、三级缓存定义三、解决流程(以ServiceA和ServiceB为例)四、关键机制详解五、设计约

解决tomcat启动时报Junit相关错误java.lang.ClassNotFoundException: org.junit.Test问题

《解决tomcat启动时报Junit相关错误java.lang.ClassNotFoundException:org.junit.Test问题》:本文主要介绍解决tomcat启动时报Junit相... 目录tomcat启动时报Junit相关错误Java.lang.ClassNotFoundException

解决Maven项目报错:failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0的问题

《解决Maven项目报错:failedtoexecutegoalorg.apache.maven.plugins:maven-compiler-plugin:3.13.0的问题》这篇文章主要介... 目录Maven项目报错:failed to execute goal org.apache.maven.pl

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法

《SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法》在SQLyog中执行存储过程时出现的前置缩进问题,实际上反映了SQLyog对SQL语句解析的一个特殊行为,本文给大家介绍了详... 目录问题根源正确写法示例永久解决方案为什么命令行不受影响?最佳实践建议问题根源SQLyog的语句分

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

MyBatis模糊查询报错:ParserException: not supported.pos 问题解决

《MyBatis模糊查询报错:ParserException:notsupported.pos问题解决》本文主要介绍了MyBatis模糊查询报错:ParserException:notsuppo... 目录问题描述问题根源错误SQL解析逻辑深层原因分析三种解决方案方案一:使用CONCAT函数(推荐)方案二:

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B