@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

相关文章

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

XML重复查询一条Sql语句的解决方法

《XML重复查询一条Sql语句的解决方法》文章分析了XML重复查询与日志失效问题,指出因DTO缺少@Data注解导致日志无法格式化、空指针风险及参数穿透,进而引发性能灾难,解决方案为在Controll... 目录一、核心问题:从SQL重复执行到日志失效二、根因剖析:DTO断裂引发的级联故障三、解决方案:修复

IDEA Maven提示:未解析的依赖项的问题及解决

《IDEAMaven提示:未解析的依赖项的问题及解决》:本文主要介绍IDEAMaven提示:未解析的依赖项的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录IDEA Maven提示:未解析的依编程赖项例如总结IDEA Maven提示:未解析的依赖项例如

怎么用idea创建一个SpringBoot项目

《怎么用idea创建一个SpringBoot项目》本文介绍了在IDEA中创建SpringBoot项目的步骤,包括环境准备(JDK1.8+、Maven3.2.5+)、使用SpringInitializr... 目录如何在idea中创建一个SpringBoot项目环境准备1.1打开IDEA,点击New新建一个项

解决Entity Framework中自增主键的问题

《解决EntityFramework中自增主键的问题》:本文主要介绍解决EntityFramework中自增主键的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录Entity Framework中自增主键问题解决办法1解决办法2解决办法3总结Entity Fram

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1