最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringMVC異常處理的三種方式

 更新時(shí)間:2024年02月19日 15:44:58   作者:兔子隊(duì)列  
在SpringMVC中異常處理是一個(gè)重要的方面,它幫助我們有效地處理應(yīng)用程序中的異常情況,提高用戶體驗(yàn)和系統(tǒng)的穩(wěn)定性,這篇文章主要給大家介紹了關(guān)于SpringMVC異常處理的三種方式,需要的朋友可以參考下

HandlerExceptionResolver接口

在SpringMVC中,提供了一個(gè)全局異常處理器,用于對(duì)系統(tǒng)中出現(xiàn)的異常進(jìn)行統(tǒng)一處理

在一般的系統(tǒng)中,DAO層、Service層及Controller層出現(xiàn)異常都以“throws Exception”的形式向上層拋出,最后都會(huì)由SpringMVC的前端控制器(DispatcherServlet)統(tǒng)一交給全局異常處理器進(jìn)行異常處理

在SpringMVC中提供的HandlerExceptionResolver接口可以實(shí)現(xiàn)全局異常處理器

Spring MVC接口HandlerExceptionResolver用于抽象一個(gè)異常解析器

這種異常解析器被用于分析請(qǐng)求處理器Handler映射或者執(zhí)行過(guò)程中的異常,將這些異常轉(zhuǎn)換成其他形式展示給用戶

可以看到,HandlerExceptionResolver接口中定義了一個(gè)名為resolveException的方法,該方法主要用于處理Controller中的異常

參數(shù)“Exception ex”即為Controller或其下層拋出的異常

參數(shù)“Object handler”就是處理器適配器要執(zhí)行的Handler對(duì)象

resolveException方法的返回值類(lèi)型是ModelAndView,也就是說(shuō),可以通過(guò)這個(gè)返回值來(lái)設(shè)置發(fā)送異常時(shí)的顯示頁(yè)面

典型的做法是轉(zhuǎn)換成一個(gè)錯(cuò)誤視圖,或者返回某個(gè)HTTP狀態(tài)碼給請(qǐng)求端

使用HandlerExceptionResolver實(shí)現(xiàn)全局異常處理器;當(dāng)拋出異常后,要有相應(yīng)的符合用戶體驗(yàn)的友好界面顯示異常

綜合實(shí)例:

(1)創(chuàng)建自定義異常類(lèi),名稱(chēng)為OperationException

注意:

Spring管理的事務(wù),無(wú)論是聲明式事務(wù)還是注解式事務(wù)默認(rèn)是在拋出運(yùn)行異常(RuntimeException異常)時(shí),才會(huì)被Spring框架捕獲到然后回滾

該自定義異常類(lèi)繼承的是RuntimeException類(lèi),因?yàn)橐话沩?xiàng)目的Service層邏輯都會(huì)使用Spring提供的事務(wù)管理,當(dāng)Service層需要拋出自定義異常時(shí),如果該自定義異常繼承的是Exception類(lèi),則Spring提供的事務(wù)管理將會(huì)失效,所以這里的自定義異常類(lèi)繼承的是RuntimeException類(lèi),這樣才不會(huì)使Spring提供的事務(wù)管理失效

(2)創(chuàng)建全局異常處理器OperationExceptionResolver類(lèi),該類(lèi)實(shí)現(xiàn)HandlerExceptionResolver接口,并且實(shí)現(xiàn)resolveException方法

(3)創(chuàng)建名稱(chēng)為error.jsp的頁(yè)面,符合用戶體驗(yàn)的友好界面,用于顯示異常信息

Spring MVC 為HandlerExceptionResolver提供了四個(gè)實(shí)現(xiàn)類(lèi)

(1)ExceptionHandlerExceptionResolver

找到使用@ExceptionHandler注解的ServletInvocableHandlerMethod并調(diào)用,基于其執(zhí)行結(jié)果構(gòu)建ModelAndView

(2)SimpleMappingExceptionResolver

映射異常類(lèi)名到視圖名稱(chēng),處理時(shí)使用此映射關(guān)系構(gòu)建ModelAndView,或者使用缺省視圖

(3)ResponseStatusExceptionResolver

如果異常是ResponseStatusException或者使用了注解@ResponseStatus,則利用這些信息將異常翻譯成HTTP狀態(tài)字調(diào)用相應(yīng)的sendError,返回空ModelAndView

注意:該異常解析器會(huì)遞歸檢查異常的cause異常

(4)DefaultHandlerExceptionResolver

Spring MVC缺省異常處理器,解析時(shí)將標(biāo)準(zhǔn)MVC異常翻譯成HTTP狀態(tài)字調(diào)用相應(yīng)對(duì)象的方法#sendError,返回一個(gè)空ModelAndView對(duì)象(注意:不是null)

使用注解實(shí)現(xiàn)異常分類(lèi)管理(@ControllerAdvice 和 @ExceptionHandler)

引言:

在開(kāi)發(fā)中,我們會(huì)有如下的場(chǎng)景:某個(gè)接口中,存在一些業(yè)務(wù)異常

例如用戶輸入的參數(shù)校驗(yàn)失敗、用戶名密碼不存在等

當(dāng)觸發(fā)這些業(yè)務(wù)異常時(shí),我們需要拋出這些自定義的業(yè)務(wù)異常,并對(duì)其進(jìn)行處理

一般我們要把這些異常信息的狀態(tài)碼和異常描述,友好地返回給調(diào)用者,調(diào)用者則利用狀態(tài)碼等信息判斷異常的具體情況

過(guò)去,我們可能需要在 controller 層通過(guò) try/catch 處理

首先 catch 自定義異常,然后 catch 其它異常

對(duì)于不同的異常,我們需要在 catch 的同時(shí)封裝將要返回的對(duì)象

然而,這么做的弊端就是代碼會(huì)變得冗長(zhǎng)

每個(gè)接口都需要做 try/catch 處理,而且一旦需要調(diào)整,所有的接口都需要修改一遍,非常不利于代碼的維護(hù),如下段代碼所示:

那么,有沒(méi)有什么方法可以簡(jiǎn)便地處理這些異常信息呢?

答案是肯定的

Spring 3.2 中,新增了 @ControllerAdvice 注解,可以用于定義 @ExceptionHandler、@InitBinder、@ModelAttribute,并應(yīng)用到所有 @RequestMapping 中

簡(jiǎn)單來(lái)說(shuō)就是,可以通過(guò) @ControllerAdvice 注解配置一個(gè)全局異常處理類(lèi),來(lái)統(tǒng)一處理 controller 層中的異常,于此同時(shí) controller 中可以不用再寫(xiě) try/catch,這使得代碼既整潔又便于維護(hù)

綜合實(shí)例:定義自定義異常

(1)自定義業(yè)務(wù)異常類(lèi)

(2)@ControllerAdvice + @ExceptionHandler 配置全局異常處理類(lèi)

@ControllerAdvice

類(lèi)型:類(lèi)注解;定義該類(lèi)為全局異常處理類(lèi)

@ExceptionHandler

類(lèi)型:方法注解;定義該方法為異常處理方法

value 的值為需要處理的異常類(lèi)的 class 文件

這樣,就可以對(duì)不同的異常進(jìn)行統(tǒng)一處理了

通常,為了使 controller 中不再使用任何 try/catch,也可以在 GlobalExceptionHandler 中對(duì) Exception 做統(tǒng)一處理

這樣其他沒(méi)有用 @ExceptionHandler 配置的異常就都會(huì)統(tǒng)一被處理

遇到異常時(shí)拋出異常即可

在業(yè)務(wù)中,遇到業(yè)務(wù)異常的地方,直接使用 throw 拋出對(duì)應(yīng)的業(yè)務(wù)異常即可

例如:

注意:

  • 不一定必須在 controller 層本身拋出異常才能被 GlobalExceptionHandler 處理,只要異常最后是從 contoller 層拋出去的就可以被全局異常處理器處理
  • 異步方法中的異常不會(huì)被全局異常處理
  • 拋出的異常如果被代碼內(nèi)的 try/catch 捕獲了,就不會(huì)被 GlobalExceptionHandler 處理了

優(yōu)點(diǎn):

  • 減少代碼冗余,代碼便于維護(hù)

缺點(diǎn):

  • 只能處理 controller 層拋出的異常,對(duì)例如 Interceptor(攔截器)層的異常、定時(shí)任務(wù)中的異常、異步方法中的異常,不會(huì)進(jìn)行處理

使用 @ControllerAdvice 對(duì)不同的 Controller 分別捕獲異常并處理

引言

  • 上文介紹了如何在 SpringBoot 工程中對(duì) Controller 配置全局異常處理
  • 后來(lái)在實(shí)際工程中,又有了如下需求:有些接口在發(fā)生異常時(shí),需要持久化錯(cuò)誤信息,而有的接口則不需要
  • 如果使用了全局異常處理,那每次發(fā)生了異常,還需要判斷是哪個(gè)接口發(fā)生的異常,進(jìn)而選擇是否持久化錯(cuò)誤日志
  • 那能不能對(duì)全局異常進(jìn)行配置,對(duì)不同類(lèi)型的接口使用不同的全局異常進(jìn)行處理呢?
  • 經(jīng)過(guò)查閱文檔發(fā)現(xiàn),Spring 提供了對(duì) @ControllerAdvice 注解的配置,我們可以通過(guò)配置 @ControllerAdvice 指定攔截范圍

@ControllerAdvice 指定 Controller 范圍

  • 根據(jù) API,我們可以看到注解 @ControllerAdvice 有如下幾種配置:

(1)basePackages

  • basePackages:指定一個(gè)或多個(gè)包,這些包及其子包下的所有 Controller 都被該 @ControllerAdvice 管理
  • 其中上面兩種等價(jià)于 basePackages

(2)basePackageClasses

  • basePackageClasses:是 basePackages 的一種變形,指定一個(gè)或多個(gè) Controller 類(lèi),這些類(lèi)所屬的包及其子包下的所有 Controller 都被該 @ControllerAdvice 管理

(3)assignableTypes

  • assignableTypes:指定一個(gè)或多個(gè) Controller 類(lèi),這些類(lèi)被該 @ControllerAdvice 管理

(4)annotations

  • annotations:指定一個(gè)或多個(gè)注解,被這些注解所標(biāo)記的 Controller 會(huì)被該 @ControllerAdvice 管理

例子

  • 這里用 assignableTypes 配置指定的 Controller 進(jìn)行測(cè)試

(1)創(chuàng)建三個(gè) Controller

其中,BusinessException 是自定義的異常類(lèi)

(2)創(chuàng)建兩個(gè)全局異常處理類(lèi)

(3)分別調(diào)用接口,查看錯(cuò)誤日志

(1)調(diào)用 localhost:8080/test1

返回:GlobalExceptionHandler1 服務(wù)錯(cuò)誤

即 MyController1 異常被 GlobalExceptionHandler1 全局異常類(lèi)捕獲

(2)調(diào)用 localhost:8080/test2

返回:GlobalExceptionHandler2 服務(wù)錯(cuò)誤

即 MyController2 異常被 GlobalExceptionHandler2 全局異常類(lèi)捕獲

(3)調(diào)用 localhost:8080/test3

返回:

即 MyController3 異常沒(méi)有被全局異常捕獲

總結(jié) 

到此這篇關(guān)于SpringMVC異常處理的三種方式的文章就介紹到這了,更多相關(guān)SpringMVC異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

容城县| 宁夏| 海原县| 临潭县| 邹平县| 竹溪县| 睢宁县| 聂拉木县| 大余县| 南充市| 靖安县| 大石桥市| 电白县| 蒙自县| 孟州市| 拉萨市| 翁牛特旗| 思南县| 同江市| 湖州市| 高唐县| 蓝田县| 蓝山县| 津南区| 综艺| 连城县| 固镇县| 大同县| 中山市| 青河县| 沽源县| 和田市| 华容县| 平定县| 清水县| 彭阳县| 浮山县| 遵义市| 阳曲县| 枣强县| 新和县|