web开发过程中,我们的Controller无法预测内部是否会发生异常,当然我们可以通过对每个Controller的方法通过try-catch进行包一层,然后对Exception进行处理,但这样带来的就是重复的代码的编写,每个方法都要有这个处理逻辑。

解决办法

Spring提供了两个注解ControllerAdvice,还有RestControllerAdvice,默认对RestController注解进行处理,具体内容可以到spring官网进行了解,

https://docs.spring.io/spring/docs/4.3.9.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#aop-ataspectj-around-advice

本文重点

ControllerAdvice注解,属于类注解,用这个注解标识的类可以对Controller进行统一拦截,我们主要用它来解决Controller层的异常问题

代码举例

如上一篇我们自定义了StatusException,我们就写一个拦截,对StatusException进行统一处理,其余异常统一用Exception进行处理,因为Exception是超类,所有他的子类都会被处理

Controller如

exception1方法,抛出StatusException

exception2方法,会抛出类型转换异常




注解实现Restcontroler超时控制 controller注解报错_@controlleradvice


两个抛出不同异常的Controller

我们写一个Controller拦截的类如下分别对StatusException和其他异常进行处理如下



注解实现Restcontroler超时控制 controller注解报错_spring_02


针对不同异常的不同处理

处理结果:

针对StatusException处理,返回map的json如下,因为有@ResponseBody注解,所以这个异常发生时被statusException方法处理,并把异常的code和msg存储到map中,然后返回给调用方一个json如下



注解实现Restcontroler超时控制 controller注解报错_json_03


StatusException异常处理返回json样式

针对Exception异常处理,通过创建ModelAndView,进行页面的跳转。就不做演示,大家可以自己尝试

知识点:

1、类需要加上ControllerAdvice注解,该注解还支持包目录,可以对不同目录写不同的拦截处理

2、异常处理要有顺序,一定要将子类异常放在第一个方法,父类异常向后排序,本文距离如果将处理Exception异常的方法放在第一个方法,则永远不会执行StatusException的异常拦截处理。

通过上述方法能够完成Controller异常的统一处理,可以将跳转页面的Controller和返回json的Controller分开,然后分别用不同的拦截进行统一处理,感谢大家,有问题多交流