吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Spring Boot怎么通過(guò)注解來(lái)實(shí)現(xiàn)全局異常處理的

科技綠洲 ? 來(lái)源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-13 10:58 ? 次閱讀

前言

在平時(shí)的 API 開(kāi)發(fā)過(guò)程中,總會(huì)遇到一些錯(cuò)誤異常沒(méi)有捕捉到的情況。那有的小伙伴可能會(huì)想,這還不簡(jiǎn)單么,我在 API 最外層加一個(gè) try...catch 不就完事了。

哈哈哈,沒(méi)錯(cuò)。這種方法簡(jiǎn)單粗暴。小編曾經(jīng)也是這么干的,但是你轉(zhuǎn)過(guò)來(lái)想一想,你會(huì)在每一個(gè) API 入口,都去做 try...catch 嗎?這樣不是代碼非常丑陋的。小伙伴開(kāi)始思考,突然靈光一現(xiàn),說(shuō)我們實(shí)現(xiàn)一個(gè) AOP 來(lái)做這事不就完了。沒(méi)錯(cuò),使用 AOP 來(lái)實(shí)現(xiàn)是最佳的選擇。

現(xiàn)在就給大家來(lái)介紹介紹 Spring Boot 怎么通過(guò)注解來(lái)實(shí)現(xiàn)全局異常處理的。

主角 @ControllerAdvice@ExceptionHandler

我們先來(lái)介紹一下今天的主角,分別是 @ControllerAdvice@ExceptionHandler

  • @ControllerAdvice 相當(dāng)于 controller 的切面,主要用于 @ExceptionHandler, @InitBinder@ModelAttribute,使注解標(biāo)注的方法對(duì)每一個(gè) controller 都起作用。默認(rèn)對(duì)所有 controller 都起作用,當(dāng)然也可以通過(guò) @ControllerAdvice 注解中的一些屬性選定符合條件的 controller
  • @ExceptionHandler 用于異常處理的注解,可以通過(guò) value 指定處理哪種類(lèi)型的異常還可以與 @ResponseStatus 搭配使用,處理特定的 http 錯(cuò)誤。標(biāo)記的方法入?yún)⑴c返回值都有很大的靈活性,具體可以看注釋也可以在后邊的深度探究。

案例分析

今天我們就通過(guò)幾種案例的方式,來(lái)給大家分析分析,怎么通過(guò)全局異常處理的方式玩轉(zhuǎn) Spring Boot 的全局異常處理。

案例一

一般的異常處理,所有的API都需要有相同的異常結(jié)構(gòu)。

圖片

exception1

在這種情況下,實(shí)現(xiàn)是非常簡(jiǎn)單的,我們只需要?jiǎng)?chuàng)建 GeneralExceptionHandler 類(lèi),用 @ControllerAdvice 注解來(lái)注解它,并創(chuàng)建所需的 @ExceptionHandler ,它將處理所有由應(yīng)用程序拋出的異常,如果它能找到匹配的 @ExceptionHandler,它將相應(yīng)地進(jìn)行轉(zhuǎn)換。

@ControllerAdvice
public class GeneralExceptionHandler {
    @ExceptionHandler(Exception.class)
    protected ResponseEntity< Error > handleException(Exception ex) {
       MyError myError = MyError.builder()
                         .text(ex.getMessage())
                         .code(ex.getErrorCode()).build();
       return new ResponseEntity(myError,
                               HttpStatus.valueOf(ex.getErrorCode()));
    }
}

案例二

我們有一個(gè)API,它需要有一個(gè)或多個(gè)異常以其他格式處理,與其他應(yīng)用程序的 API 不同。

圖片

exception2

我們可以采取兩種方式來(lái)實(shí)現(xiàn)這種情況。我們可以在 OtherController 內(nèi)部添加 @ExceptionHandler 來(lái)處理 OtherException ,或者為 OtherController 創(chuàng)建新的@ControllerAdvice,以備我們也想在其他 API 中處理 OtherException

OtherController 中添加 @ExceptionHandler 來(lái)處理 OtherException 的代碼示例。

@RestController
@RequestMapping("/other")
public class OtherController {
    @ExceptionHandler(OtherException.class)
    protected ResponseEntity< Error > handleException(OtherException ex) {
      MyOtherError myOtherError = MyOtherError.builder()
                         .message(ex.getMessage())
                         .origin("Other API")
                         .code(ex.getErrorCode()).build();
      return new ResponseEntity(myOtherError,
                               HttpStatus.valueOf(ex.getErrorCode()));
    }
}

只針對(duì) OtherController 控制器@ControllerAdvice 的代碼示例

@ControllerAdvice(assignableTypes = OtherController.class)
public class OtherExceptionHandler {
    @ExceptionHandler(OtherException.class)
    protected ResponseEntity< Error > handleException(OtherException ex) {
      MyOtherError myOtherError = MyOtherError.builder()
                         .message(ex.getMessage())
                         .origin("Other API")
                         .code(ex.getErrorCode()).build();
      return new ResponseEntity(myOtherError,
                               HttpStatus.valueOf(ex.getErrorCode()));
    }
}

案例三

與案例二類(lèi)似,我們有一個(gè) API 需要以不同于應(yīng)用程序中其他 API 的方式對(duì)異常進(jìn)行格式化,但這次所有的異常都需要進(jìn)行不同的轉(zhuǎn)換。

圖片exception3

為了實(shí)現(xiàn)這個(gè)案例,我們將不得不使用兩個(gè) @ControllerAdvice,并加上 @Order 注解的注意事項(xiàng)。因?yàn)楝F(xiàn)在我們需要告訴 Spring,在處理同一個(gè)異常時(shí),哪個(gè) @ControllerAdvice 的優(yōu)先級(jí)更高。如果我們沒(méi)有指定 @Order,在啟動(dòng)時(shí),其中一個(gè)處理程序?qū)⒆詣?dòng)注冊(cè)為更高的順序,我們的異常處理將變得不可預(yù)測(cè)。例如,我最近看到一個(gè)案例,如果你使用 mvn springboot:run 任務(wù)啟動(dòng)一個(gè)應(yīng)用程序,OtherExceptionHandler 是主要的,但是當(dāng)以jar形式啟動(dòng)時(shí),GeneralExceptionHandler 是主要的。

@ControllerAdvice
public class GeneralExceptionHandler {
    @ExceptionHandler(Exception.class)
    protected ResponseEntity< Error > handleException(Exception ex) {
       MyError myError = MyError.builder()
                         .text(ex.getMessage())
                         .code(ex.getErrorCode()).build();
       return new ResponseEntity(myError,
                               HttpStatus.valueOf(ex.getErrorCode()));
    }
}
@ControllerAdvice(assignableTypes = OtherController.class)
@Order(Ordered.HIGHEST_PRECEDENCE)
public class OtherExceptionHandler {
    @ExceptionHandler(Exception.class)
    protected ResponseEntity< Error > handleException(Exception ex) {
       MyError myError = MyError.builder()
                         .message(ex.getMessage())
                         .origin("Other API")
                         .code(ex.getErrorCode()).build();
       return new ResponseEntity(myError,
                               HttpStatus.valueOf(ex.getErrorCode()));
    }
}

總結(jié)

經(jīng)過(guò)上述的幾個(gè)案例,指北君覺(jué)得大家應(yīng)該已經(jīng)能夠輕松應(yīng)對(duì) Spring Boot 中大部分的全局異常處理的情況。

細(xì)心的同學(xué)也許會(huì)覺(jué)得為什么不使用 @RestControllerAdvice 呢?如果是用的 @RestControllerAdvice 注解,它會(huì)將數(shù)據(jù)自動(dòng)轉(zhuǎn)換成JSON格式,不再需要 ResponseEntity 的處理來(lái)。這種與 ControllerRestController 類(lèi)似,本質(zhì)是一樣的,所以我們?cè)谑褂萌之惓L幚碇罂梢赃M(jìn)行靈活的選擇處理。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1511

    瀏覽量

    62399
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4827

    瀏覽量

    69055
  • SpringBoot
    +關(guān)注

    關(guān)注

    0

    文章

    174

    瀏覽量

    201
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Spring Boot如何實(shí)現(xiàn)異步任務(wù)

    Spring Boot 提供了多種方式來(lái)實(shí)現(xiàn)異步任務(wù),這里介紹三種主要實(shí)現(xiàn)方式。 1、基于注解
    的頭像 發(fā)表于 09-30 10:32 ?1475次閱讀

    啟動(dòng)Spring Boot項(xiàng)目應(yīng)用的三種方法

    首先大家了解什么是Spring BootSpring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用
    發(fā)表于 01-14 17:33

    使用Spring自定義注解實(shí)現(xiàn)

    執(zhí)行器。其本質(zhì)就是通過(guò)外部參數(shù)進(jìn)行一次路由和Spring mvc做的事情類(lèi)似。簡(jiǎn)單看了Spring mvc的實(shí)現(xiàn)原理之后,決定使用自定義注解
    發(fā)表于 09-28 11:55 ?0次下載

    Spring Boot框架錯(cuò)誤處理

    》 《strong》翻譯《/strong》:雁驚寒《/p》 《/blockquote》《p》《em》摘要:本文通過(guò)實(shí)例介紹了使用Spring Boot在設(shè)計(jì)API的時(shí)候如何正確地對(duì)異常
    發(fā)表于 09-28 15:31 ?0次下載

    Spring Boot 系列(八)@ControllerAdvice 攔截異常并統(tǒng)一處理

    Spring Boot 系列(八)@ControllerAdvice 攔截異常并統(tǒng)一處理spring 3.2中,新增了@Controll
    發(fā)表于 01-16 18:39 ?316次閱讀

    Spring Boot Web相關(guān)的基礎(chǔ)知識(shí)

    Boot的第一個(gè)接口。接下來(lái)將會(huì)將會(huì)介紹使用Spring Boot開(kāi)發(fā)Web應(yīng)用的相關(guān)內(nèi)容,其主要包括使用spring-boot-starter-web組件
    的頭像 發(fā)表于 03-17 15:03 ?696次閱讀

    簡(jiǎn)述Spring Boot數(shù)據(jù)校驗(yàn)

    上一篇文章我們了解了Spring Boot Web相關(guān)的知識(shí),初步了解了spring-boot-starter-web,還了解了@Contrler和@RestController的差別,如果
    的頭像 發(fā)表于 03-17 15:07 ?824次閱讀

    Spring Web MVC注解

    RequestMapping注解的主要用途是將Web請(qǐng)求與請(qǐng)求處理類(lèi)中的方法進(jìn)行映射。Spring MVC和Spring WebFlux都通過(guò)
    的頭像 發(fā)表于 04-07 11:32 ?655次閱讀
    <b class='flag-5'>Spring</b> Web MVC<b class='flag-5'>注解</b>

    Spring Bean相關(guān)的4個(gè)注解及使用方法

    ComponentScan`注解用于配置Spring需要掃描的被組件注解注釋的類(lèi)所在的包。可以通過(guò)配置其basePackages屬性或者value屬性
    的頭像 發(fā)表于 04-07 11:33 ?1393次閱讀
    <b class='flag-5'>Spring</b> Bean相關(guān)的4個(gè)<b class='flag-5'>注解</b>及使用方法

    容器配置及Spring Boot注解

    Autowired注解用于標(biāo)記Spring將要解析和注入的依賴(lài)項(xiàng)。此注解可以作用在構(gòu)造函數(shù)、字段和setter方法上。
    的頭像 發(fā)表于 04-07 11:45 ?615次閱讀
    容器配置及<b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b><b class='flag-5'>注解</b>

    Spring中@Component注解是怎么實(shí)現(xiàn)

    想必`@Component`注解大家一直在使用,只要類(lèi)上加上它,就可以被Spring容器管理,那大家有想過(guò)它是怎么實(shí)現(xiàn)的嗎?本篇文章就帶領(lǐng)到家揭秘。
    的頭像 發(fā)表于 04-07 15:23 ?1659次閱讀
    <b class='flag-5'>Spring</b>中@Component<b class='flag-5'>注解</b>是怎么<b class='flag-5'>實(shí)現(xiàn)</b>的

    Spring Boot啟動(dòng) Eureka流程

    Spring Boot 啟動(dòng) eureka 的關(guān)鍵注解就在 @EnableEurekaServer 上面。 @Target ({ElementType.TYPE}) @Retention
    的頭像 發(fā)表于 10-10 11:40 ?930次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>啟動(dòng) Eureka流程

    Spring Boot的啟動(dòng)原理

    可能很多初學(xué)者會(huì)比較困惑,Spring Boot 是如何做到將應(yīng)用代碼和所有的依賴(lài)打包成一個(gè)獨(dú)立的 Jar 包,因?yàn)閭鹘y(tǒng)的 Java 項(xiàng)目打包成 Jar 包之后,需要通過(guò) -classpath 屬性
    的頭像 發(fā)表于 10-13 11:44 ?688次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>的啟動(dòng)原理

    Spring Boot 的設(shè)計(jì)目標(biāo)

    ,這樣我們就可以盡快的上手。 使用 Spring Boot 來(lái)不僅可以創(chuàng)建基于 war 方式部署的傳統(tǒng)Java應(yīng)用程序,也可以通過(guò)創(chuàng)建獨(dú)立的不依賴(lài)任何容器(如 tomcat 等)
    的頭像 發(fā)表于 10-13 14:56 ?617次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b> 的設(shè)計(jì)目標(biāo)

    springboot核心注解

    Spring Boot 是基于 Spring 框架的開(kāi)源框架,它可以幫助開(kāi)發(fā)者快速構(gòu)建、部署和運(yùn)行獨(dú)立的、生產(chǎn)級(jí)的 Spring 應(yīng)用程序。Spri
    的頭像 發(fā)表于 11-23 09:23 ?559次閱讀
    牡丹江市| 456棋牌游戏| 百家乐游戏机压法| 上海百家乐官网赌博| 大发888官网 df888ylcxz46| 百家乐官网首页红利| 大发888免费游戏| 现金百家乐破解| 百家乐官网稳赢秘诀教学| 全球最大赌博网站| 金彩百家乐的玩法技巧和规则 | 保单机百家乐官网破解方法| 最好的棋牌游戏平台| 希尔顿百家乐试玩| 明溪百家乐官网的玩法技巧和规则 | 新世纪百家乐官网的玩法技巧和规则 | 合乐娱乐| 威尼斯人娱乐城安全吗| 百家乐视频台球游戏| 百家乐官网在线娱乐平台| 班玛县| 大发888客户端软件| 娱乐城百家乐送白菜| 百家乐出租平台| 百家乐官网筹码500| 永城市| bet365体育投注提款要几天| 百家乐博彩破解论坛| 百家乐注册开户送现金| 百家乐官网博彩公| 申请百家乐官网会员送彩金| 爱赢娱乐城开户| 大发888体育网| 赌百家乐容易的原| 网上百家乐哪里开户| 百家乐官网群dmwd| 百家乐官网旺门打法| 澳门1百家乐官网网| 豪博百家乐官网现金网| 石泉县| 百家乐打法|