Spring MVC 异常处理方式

发布时间:2023-07-10 10:36:34     来源:实战案例锦集

当程序发生异常时我们可以通过如下两个注解来统一处理异常信息。


(资料图片)

@ControllerAdvice 和 @RestControllerAdvice

他们的区别其实就是Rest的注解中多了一个@ResponseBody 注解(将方法的返回值,以特定的格式写入到response的body,进而将数据返回给客户端,如果是字符串直接输出字符串信息,如果是对象将会把对象转为json进行输出)。

源码:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface ControllerAdvice {}@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@ControllerAdvice@ResponseBodypublic @interface RestControllerAdvice {}
方式一、Controller内部处理异常
@RestControllerpublic class TestController {    @GetMapping("/test/{id}")  public Object test(@PathVariable Integer id) {    if (id < 5) {      throw new RuntimeException("运行时异常") ;    }    return "测试异常处理" ;  }    @ExceptionHandler  public Object handle(Exception e) {    return e.getMessage() ;  }  }

这样如果这个Controller中的接口发生了异常那么就会执行有@ExceptionHandler标注的方法。

该种方式处理异常只是针对当前Controller,一个项目肯定会有很多的Controller,如果每一个类都这样处理明显是太麻烦,而且还不方便统一异常的处理。

方式二、全局异常处理

可以在一个类上添加 @RestControllerAdvice或@ControlerAdvice

@RestControllerAdvicepublic class TestControllerAdvice {  @ExceptionHandler  public Object handle(Exception e) {    return "我是全局异常:" + e.getMessage() ;  }  }

到此全局异常的使用方式就结束了当你访问接口时你会发现全局异常没有起作用。

当我们把controller中的@ExceptionHandler注释了,这时全局异常才会生效。

结论:局部异常处理优先级高于全局异常处理。

以上是项目中如果使用异常处理句柄的方式;接下来我们来看看在全局异常处理句柄中如何进行局部控制(比如只处理有特定注解的或是只处理部分controller又或者是指定包下的controller)。

1、只处理特定注解

自定义Annotation:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface AppAnnotation {}

Controller类:

有@AppAnnotation注解的Controller

@AppAnnotation@RestControllerpublic class AnnotationController {  @GetMapping("/an/get/{id}")  public Object an(@PathVariable Integer id) {    if (id < 10) {      throw new RuntimeException("发生错误了") ;    }    return "自定义Annotation注解: " + id ;  }  }

没有@AppAnnotation注解的Controller

@RestControllerpublic class AnnotationController2 {    @GetMapping("/an/get2/{id}")  public Object an(@PathVariable Integer id) {    if (id < 10) {      throw new RuntimeException("2发生错误了") ;    }    return "自定义Annotation注解2: " + id ;  }}

ControllerAdvice异常处理类:

@RestControllerAdvice(annotations = {AppAnnotation.class})public class AnnotationControllerAdvice {    @ExceptionHandler  public Object handle(Exception e) {    return "特定注解全局异常:" + e.getMessage() ;  }  }

分别访问/an/get/1 和/an/get2/1接口,只有有@AppAnnotation注解的Controller会被处理。

2、只处理指定的Controller

新建UserController

@RestControllerpublic class UserController {      @GetMapping("/user/{id}")  public Object get(@PathVariable Integer id) {    if (id < 10) {      throw new RuntimeException("用户ID错误") ;    }    return "Users" ;  }  }

新建PersonController

@RestControllerpublic class PersonController {      @GetMapping("/person/{id}")  public Object get(@PathVariable Integer id) {    if (id < 10) {      throw new RuntimeException("Person ID错误") ;    }    return "Person" ;  }  }

全局异常处理类:

@RestControllerAdvice(assignableTypes = {UserController.class})public class SpecificControllerAdvice {    @ExceptionHandler  public Object handle(Exception e) {    return "指定Controller全局异常:" + e.getMessage() ;  }  }

这里通过assignableTypes属性来限定了只有UserController类发生了异常才会做出响应。

PersonController发生异常不会被处理。

3、指定包下的Controller
@RestControllerAdvice(basePackages = {"com.pack.pkg1"})public class PackageControllerAdvice {    @ExceptionHandler  public Object handle(Exception e) {    return "指定包下的全局异常:" + e.getMessage() ;  }  }

UserController类位于pkg1包下:

package com.pack.pkg1;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;@RestController("userPController")public class UserController {  @GetMapping("/userp/{id}")  public Object get(@PathVariable Integer id) {    if (id < 10) {      throw new RuntimeException("用户ID错误") ;    }    return "Users" ;  }}

PersonController类位于pkg2包下:

package com.pack.pkg2;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;@RestController("personPController")public class PersonController {  @GetMapping("/personp/{id}")  public Object get(@PathVariable Integer id) {    if (id < 10) {      throw new RuntimeException("Person ID错误") ;    }    return "Person" ;  }}

当访问com.pack.pkg1包下的接口出现异常后就会被处理。

到此结束

关于@ExceptionHandler 方法句柄可接受的参数及返回值大家可参考这里

接受的参数类型

标签:

精彩推送

代销和经销的区别是什么 代销和经销的区别

1、经销是经过品牌商授权,以自己的名义销售。2、而代销是没有授权,仅

2023-07-10

2022~2023年广西养老金上调方案新消息和广西养老金调整细则最新消息(全文)

2023年的养老金调整已经确定啦,这是因为在5月22号这一天的时候,人社

2023-07-10

国企花1160万买6辆环卫车引质疑 基本情况讲解

大家好,今日关于【国企花1160万买6辆环卫车引质疑】迅速上了的热搜榜

2023-07-10

音乐综艺掀起“说唱”热

音乐综艺掀起“说唱”热-"  青年说唱竞演节目《新说唱时代》是腾讯视

2023-07-10

歌手黄安辟谣费玉清重病传闻:真的太假了

费玉清新浪娱乐讯7日,歌手黄安发文辟谣费玉清病重传闻:“关于小哥重

2023-07-10

除草机器人“大比武”

日前,“农机地头展——全国玉米大豆智能化机械化除草作业现场会”在北

黑龙江省龙睿公司荣获第32届哈洽会“优秀组织奖”和“优秀设计奖”

黑龙江经济网讯(通讯员于永吉)第三十二届哈尔滨国际经济贸易洽谈会已

户外游玩 乐享暑期

7月9日,人们在天安门广场参观游览。新华社记者任超摄时值周末,许多市

Spring MVC 异常处理方式

当程序发生异常时我们可以通过如下两个注解来统一处理异常信息。@Contr

大庆油田上半年生产原油超1500万吨

图片由大庆油田提供本报讯(闫婷婷记者刘楠赵吉会)今年上半年,大庆油

动物园“科技+文旅”打造觅光之旅

这个夏夜,和小动物来一场奇遇。昨获悉,“无锡动物园夏季狂欢夜——觅

让“四上”企业上得去、留得住、发展好

日前,区委书记温助民率队专题调研“四上”企业培育工作,梅县区召开“

蜀山陶集打造宜兴陶文化客厅

古街边,蠡河旁,宜兴蜀山陶集已初绽芳容,完成近90%的工程量。近期,

我国成功发射卫星互联网技术试验卫星

7月9日19时0分,我国在酒泉卫星发射中心使用长征二号丙运载火箭,成功

地铁站里有“清凉一夏”

炎炎夏日,面对不断升高的气温,无锡地铁依托公共资源将地铁站变身“清

EIA周度数据公布 原油价格再度进入震荡节奏

7月7日,国内上海SC原油期货开盘报555 8元 桶,截至发稿,原油期货跌0

无锡会展经济释放回暖“强音”

今年以来,无锡会展业复苏反弹强劲,线下会展倍增式回暖。昨日记者从市

太湖周边河网区16站水位超警

据新华社北京7月9日电水利部9日发布汛情通报,7月6日至8日,西南中东部

东胜区人民检察院开展“八大任务”专项督查行动 推动重点工作落实见效

为扎实推动自治区政法委“八大专项行动”和院党组部署重点工作走深做实

代销和经销的区别是什么 代销和经销的区别

1、经销是经过品牌商授权,以自己的名义销售。2、而代销是没有授权,仅

过20℃的夏天 到临沧寻一方清凉(凤庆篇)

临沧是能与全球避暑名城榜的法国巴黎、奥地利维也纳、日本长野等媲美的

“Z世代”画像中国|一群洋大学生的太极“初体验”

仅用了4天时间,在太极拳发源地河南焦作,华南师范大学埃及留学生马都

责任与实力并行 龙湖集团上半年交付6.2万套住宅

责任与实力并行龙湖集团上半年交付6 2万套住宅,住宅,交房,碧桂园,龙湖

2022~2023年广西养老金上调方案新消息和广西养老金调整细则最新消息(全文)

2023年的养老金调整已经确定啦,这是因为在5月22号这一天的时候,人社

起拍总价约16亿元!!瑞安挂牌百亩“巨无霸”地块,楼面价…

起拍总价约16亿元!!瑞安挂牌百亩“巨无霸”地块,楼面价…,配建,代建

丁雪钦出席晋中市安委会第四次全体扩大会议

7月7日,晋中市安委会第四次全体扩大会议召开,市委常委、常务副市长丁

湖南黄金7月10日盘中涨幅达5%

以下是湖南黄金在北京时间7月10日10:10分盘口异动快照:7月10日,湖南

有信儿了!中北镇万卉路地块出规划!户均130平米!

有信儿了!中北镇万卉路地块出规划!户均130平米!,户均,洋房,中北镇,

海南:退证!

海南:退证!,原件,退证,身份证,不动产登记,房屋所有权证

民航局出手遏制机闹

中国民航飞行学院副教授钟凯介绍,常见的“机闹”行为包括打架斗殴,抢

“鲜味”如何从枝头直达手头(经济新方位)

数据来源:国家邮政局等制图:汪哲平“叮咚——”下午3点09分,上海浦

第二十九届兰洽会强工业行动发展论坛在兰州举行

第二十九届兰洽会强工业行动发展论坛在兰州举行

我省打造“龙江模式”家庭医生

□本报记者李美时头疼脑热可以随时电话咨询,不出小区可以购买到集中带

8万余尾施氏鲟鱼苗放流松花江

本报讯(记者李天池)日前,省水生动物资源养护中心在松花江佳木斯段成

【相约兰洽 共筑未来】企业有信心在甘肃投资发展

新甘肃·甘肃日报记者曹立萍展台前,交流沟通,洽谈合作;展馆里,展品

“备战”亚运进行时!义乌足球生产企业订单排到11月

(央视财经《经济信息联播》)随着亚运会举办时间越来越近,各家企业都

私募基金行业首部行政法规亮相 夯实行业发展法治基础

随着《私募投资基金监督管理条例》(以下简称《条例》)正式对外发布,

打造世界级农产品品牌

□本报记者刘晓云6月8日,为期三天的全国食用菌(黑木耳)产业高质量发

你提需求我拿项目 龙粤两地对接忙

黑龙江—广东外企经贸投资合作大会现场。广东外企团队在我省考察。考察

国企花1160万买6辆环卫车引质疑 基本情况讲解

大家好,今日关于【国企花1160万买6辆环卫车引质疑】迅速上了的热搜榜

2022年五大强省份城市对比:佛山VS厦门VS温州VS烟台

2022年五大强省份城市对比:佛山VS厦门VS温州VS烟台,烟台,广东,山东,厦

中国20城市引擎 贡献巨GDP 带来低生活水平?

中国20城市引擎贡献巨GDP带来低生活水平?,中国,生活水平,生活品质

潘集区棚改区安置项目(珠江东路)规划方案公示

潘集区棚改区安置项目(珠江东路)规划方案公示,潘集区,棚改区,规划设

宏观利空扰动 双焦盘面震荡运行

【宏观利空扰动双焦盘面震荡运行】受焦炭提涨落地影响,蒙煤价格有所反

滁州的发展现状与潜力——迈向财政净上缴城市

滁州的发展现状与潜力——迈向财政净上缴城市,芜湖,合肥,财政,马鞍山,

音乐综艺掀起“说唱”热

音乐综艺掀起“说唱”热-"  青年说唱竞演节目《新说唱时代》是腾讯视

孝庄与多尔衮究竟什么关系?他们真的相爱吗?

1634年,苏茉儿突然问孝庄,“您没想多尔衮当上大汗,然后……”话说到

“全球最热一天”纪录接连被打破 四天内三天出现新高

“全球最热一天”纪录接连被打破四天内三天出现新高

交银国际指香港放宽按揭成数料带动购房情绪 看好新鸿基地产(00016)

交银国际发研报指,香港按揭贷款公司与金管局于7月7日晚间联合宣布,提

信用卡逾期1天利息怎么算利率?信用卡逾期要坐牢吗?

信用卡逾期1天利息怎么算利率?正常情况下逾期一天利息是本金的0 05%,也就是万分之五。首先也要分情况,如果持卡人一分钱都没有还款,银行

信用卡逾期3天会上信用吗?信用卡逾期3天有利息吗?

信用卡逾期3天会上信用吗?1、 一般来说银行都会设置1-3天的宽限期,例如交通银行、农业银行、夏银行、招商银行等等,就是为了给那些因为个

阿斯报:威廉-卡瓦略正在等待利雅得胜利完成引进他...

阿斯报:威廉-卡瓦略正在等待利雅得胜利完成引进他的交易据西班牙《阿

信用卡还不起了怎样与银行协商?银行同意协商还款后该怎么办?

信用卡还不起了怎样与银行协商?首先,我们需要主动向银行说明自己未能及时还款的原因,表明自己并非恶意逾期,并表达自己积极还款的意愿。

信用卡逾期一天利息是多少?信用卡逾期了怎么跟银行协商解决?

信用卡逾期一天利息是多少?信用卡的逾期利息分为两种,一种是逾期利息,另一种是违约金。一旦产生逾期行为,哪怕只是逾期一天,收取的就不

信用卡逾期1天会有不良记录吗?信用卡逾期1天会影响房贷吗?

信用卡逾期1天会有不良记录吗?信用卡逾期一天会不会有不良记录,要根据具体情况而定。现在很多银行都会为持卡用户提供容时服务,也就是宽限

精彩推荐