springMVC-15 異常處理

異常處理-基本介紹

  • 基本介紹

1.Spring MVC通過HandlerExceptionResolver處理程序的異常,包括Handler映射、數據綁定以及目標方法執行時發生的異常。
2.主要處理Handler中用@ExceptionHandler注解定義的方法。
3.ExceptionHandlerMethodResolver內部若找不到@ExceptionHandler注解的話,會找@ControllerAdvice類的@ExceptionHandler注解方法,這樣就相當于一個全局異常處理器

異常類型

1.局部異常

在注釋了@Controller的處理器類Handler,內部寫的異常處理,就是局部異常

需要使用注解@在其方法上進行標注

應用實例

處理原因:如果不處理異常,顯示界面會非常的不友好

1.創建com/stein/springMVC/exception/MyExceptionHandler.java

注意:

? ? ? ? 1)Handler要用@Component注入到容器中

? ? ? ? 2)局部異常處理方法,用使用@ExceptionHandler進行注解

? ? ? ? 3)@ExceptionHandler的參數,是填寫異常類型,并且可以是數組的形式

@Controller
public class MyExceptionHandler {//一個正常的方法映射@RequestMapping("/arithmetic")public String exceptionDemo(Integer num){Integer result=100/num;System.out.println("result= "+result);return "success";}@ExceptionHandler({ArithmeticException.class, NullPointerException.class})public String exceptionHandler(Exception exception, HttpServletRequest request){System.out.println("exception= "+exception.getMessage());request.setAttribute("exception", exception.getMessage());return "exception_msg";}}

2.創建操作頁面 web/exception.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>exception</title>
</head>
<body><h1>局部異常處理</h1><a href="<%=request.getContextPath()%>/arithmetic?num=0">點擊顯示算數異常</a>
</body>
</html>

3.創建異常顯示頁面,web/WEB-INF/page/exception_msg.jsp

<body><h1>出錯啦>_<</h1><h2>出錯信息:<%=request.getAttribute("exception")%></h2>
</body>

4.測試

然后顯示出錯信息

Debug代碼

????????異常是通過ExceptionHandlerMethodResolver.java類來處理的,它的異常處理機制比較多。通過Ctrl+N找到

? ? ? ? 通過形參exceptionType拿到異常,然后再拿到處理異常的method,最后通過反射調用。

????????這一步是通過默認的方法查找異常處理方法,沒有找到就返回null

Method method = (Method)this.exceptionLookupCache.get(exceptionType);

? ? ? ? 然后找到了我寫的MyExceptionHandler.exceptionHanler(exception,request)方法

? ? ? ?

????????不出意外的,找到了我寫的異常處理方法

? ? ? ? 最終返回前端頁面進行展示

2.全局異常

應用實例

????????全局異常處理機制:

????????如果在ExceptionHandlerMethodResolver內部找不到@ExceptionHandler注解的話,
????????會去@ControllerAdvice類找@ExceptionHandler注解方法,這樣就相當于一個全局異常處理器

1.創建全局異常類,com/stein/springMVC/exception/GlobalException.java

//加入這個注解后,就表示是一個全局異常
//全局異常就不管是哪個Handler拋出的異常,都可以捕獲
//控制通知
@ControllerAdvice
public class GlobalException {//注解參數用于指定,需要捕獲的異常類型//1. 模擬NumberFormatException//2. 在之前的局部異常中,沒有對NumberFormatException異常進行涵蓋//3. 所以就會來找全局異常處理@ExceptionHandler({NumberFormatException.class, ClassCastException.class})public String global(Exception ex, HttpServletRequest request) {System.out.println("全局異常信息:"+ex.getMessage());request.setAttribute("exception", ex.getMessage());return "exception_msg";}
}

2.增加出現轉換異常的方法,com/stein/springMVC/exception/MyExceptionHandler.java

    @RequestMapping("/global")public String globalExceptionDemo(String num){int i = Integer.parseInt(num);return "success";}

3.修改頁面,增加裝換異常訪問請求exception.jsp

<body><h1>異常處理</h1><a href="<%=request.getContextPath()%>/arithmetic?num=0">點擊顯示局部異常</a><br><a href="<%=request.getContextPath()%>/global?num=hello">點擊顯示全局異常</a>
</body>

4.測試

? ? ? ? 選擇全局異常

? ? ? ? 顯示全局異常提示信息

5.postman測試

Debug處理流程

? ? ? ? 依然點擊全局異常

? ? ? ? 斷點不變,可以看到發生了數字格式化異常,這一步method沒有找到處理異常方法,為null

? ? ? ? 看到此時,method找不到在@Controller類中的局部異常處理方法,顯示noMatchingExceptionHandler,沒有匹配的異常處理

? ? ? ? 找到了全局異常處理方法

? ? ? ? ?進入到處理方法

? ? ? ? 最終成功顯示異常信息

注意事項與細節

????????異常處理時:局部異常優先級高于全局異常

? ? ? ? 給局部異常處理添加上NumberFormatException.class后,局部異常優先處理

????????局部異常exception= For input string: "hello"

3.自定義異常(類型)

? ? ? ? 局部異常和全局異常,是通過作用范圍來區分的。

? ? ? ? 自定義異常,說的是自定義異常的類型。比如有ArithmeticException.class, NullPointerException.class,NumberFormatException.class這些異常了,我還需要自定義一個年齡異常AgeException.class

????????通過@ResponseStatus注解,可以自定義該異常

? ? ? ? 關系:那么自定義異常(類型),可以通過默認tomcat調用,或者局部異常、全局異常進行選擇調用。像這樣:

@ExceptionHandler({ArithmeticException.class, NullPointerException.class,NumberFormatException.class,ArithmeticException.class})
應用實例

1.創建自定義異常類型,com/stein/springMVC/exception/AgeException.java

//reason表示顯示的錯誤原因
//value填寫Http錯誤狀態,是枚舉類型的
@ResponseStatus(value = HttpStatus.BAD_REQUEST,reason = "年齡需要在1-120歲之間")
public class AgeException extends RuntimeException {
}

2.添加可能出現自定義異常的方法,MyExceptionHandler.java

    @RequestMapping("/age")public String age(int age){if(age>0 && age<120){return "success";}else {throw new AgeException();}}

3.添加訪問鏈接,exception.jsp

<a href="<%=request.getContextPath()%>/age?age=121">點擊顯示自定義異常</a><br><br>

4.測試

? ? ? ? 自定義異常(類型)

????????返回結果


這個tomcat默認頁面太生硬,想用自己頁面顯示

1.把AgeException.class添加到GlobalException.global()的注解中

@ExceptionHandler({NumberFormatException.class, ClassCastException.class,AgeException.class})

2.為了配合exception_msg.jsp的屬性exception.getMessage()返回結果不為null,添加AgeException.java的構造器

@ResponseStatus(value = HttpStatus.BAD_REQUEST,reason = "年齡需要在1-120歲之間")
public class AgeException extends RuntimeException {public AgeException() {}public AgeException(String message) {super(message);}
}

3.業務代碼中,完善message

    @RequestMapping("/age")public String age(int age){if(age>0 && age<120){return "success";}else {throw new AgeException("年齡需要在1-120歲之間");}}

4.再次測試

點擊自定義異常后,出現了我們自己寫的異常頁面exception_msg.jsp

同樣,這個自定義異常類型,添加到局部異常也可以生效,這兒就不演示了。

Debug處理流程

? ? ? ? 跟全局異常Debug一樣,參考走一遍即可。

統一處理異常信息

SimpleMappingExceptionResolver

  • 基本說明

1.如果希望對所有異常進行統一處理,可以使用SimpleMappingExceptionResolver
2.它將異常類名映射為視圖名,即發生異常時使用對應的視圖報告異常
3.需要在ioc容器中配置

應用實例

1.配置SimpleMappingExceptionResolver

    <!--配置一個統一異常處理--><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><!--這個屬性用于設置異常映射,即當發生某種異常時,應該跳轉到哪個視圖。--><property name="exceptionMappings"><!--它包含一個`<props>`標簽,這是Spring配置中用于定義`java.util.Properties`類型屬性的方式。每個`<prop>`標簽表示一個鍵值對。--><props><!--鍵(key)是異常類的全限定名--><!--值(value)是`arrEx`,是一個邏輯視圖頁面--><prop key="ArrayIndexOutOfBoundsException">arrEx</prop></props></property></bean>

2.按配置創建異常視圖,web/WEB-INF/page/arrEx.jsp

<h1>朋友,當前頁面異常>_<,如有疑問,可以聯系管理員</h1>

3.增加出現數組越界的映射方法,MyExceptionHandler

@RequestMapping("/array")
public String array(){//兩種寫法都可以int[] ints = {1, 3, 6, 12};//int[] ints =new int[]{1,3,6,12};//越界異常System.out.println("ints[5]="+ints[5]);return "success";
}

4.添加訪問頁面的鏈接,exception.jsp

    <a href="<%=request.getContextPath()%>/array">點擊測試統一異常處理</a><br><br>

5.測試

對未知異常統一處理

? ? ? ? 異常的情況有很多,當無法對每一種異常都進行單獨配置的時候,需要一種兜底的方案,就是對其他異常的統一處理。

應用實例

1.使用SimpleMappingExceptionResolver進行配置,web/WEB-INF/springMVC-servlet.xml

    <!--配置一個統一異常處理--><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><!--這個屬性用于設置異常映射,即當發生某種異常時,應該跳轉到哪個視圖。--><property name="exceptionMappings"><!--它包含一個`<props>`標簽,這是Spring配置中用于定義`java.util.Properties`類型屬性的方式。每個`<prop>`標簽表示一個鍵值對。--><props><!--鍵(key)是異常類的全限定名--><!--值(value)是`arrEx`,是一個邏輯視圖頁面--><prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop><!--兩種寫法都可以,但是推薦上面一種,避免重名--><!--<prop key="ArrayIndexOutOfBoundsException">arrEx</prop>--><!--配置其他的未知異常--><!--key配置的是所有異常Exception--><!--響應的頁面名稱是allEx--><prop key="java.lang.Exception">allEx</prop></props></property></bean>

2.創建響應頁面,web/WEB-INF/page/allEx.jsp

    <h1>哎呀,發生了未知異常>_<</h1>

3.添加未知異常映射方法,MyExceptionHandler.java

? ? ? ? 這是一個字符串越界異常

    @RequestMapping("/unknown")public String unknownException(){String str="hello";System.out.println("str.charAt[5]="+str.charAt(5));return "success";}

4.添加訪問鏈接,exception.jsp

    <a href="<%=request.getContextPath()%>/unknown">配置統一的未知異常處理</a><br><br>

5.測試

哎呀,發生了未知異常>_<

異常處理的優先級

???????

?局部異常 > 全局異常 > SimpleMappingExceptionResolver > tomcat默認機制

1.對比測試局部異常、全局異常、SimpleMappingExceptionResolver的優先級,他們3個的范圍都加上ArrayIndexOutOfBoundsException.class,然后進行數組越界異常測試。

? ? ? ? 結果響應的只有局部異常:

局部異常exception= 5

2.接下來取消局部異常的參賽資格,取消其ArrayIndexOutOfBoundsException.class的設置,將剩下2個的進行對比。然后進行數組越界異常測試。

? ? ? ? 此時,響應的是全局異常

全局異常信息:5

3.然后全局異常退出,刪除其越界異常的設置,只保留SimpleMappingExceptionResolver的設置,進行越界測試。

? ? ? ? 結果是按照SimpleMappingExceptionResolver配置的arrEx.jsp進行了響應

朋友,當前頁面異常>_<,如有疑問,可以聯系管理員

4.將SimpleMappingExceptionResolver的設置也取消,包括越界異常和所有異常。進行越界測試

? ? ? ? 結果,Tomcat默認的異常機制開始生效了

? ? ? ? 綜上,確認了他們的優先級排序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/910533.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/910533.shtml
英文地址,請注明出處:http://en.pswp.cn/news/910533.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

視頻匯聚EasyCVR平臺v3.7.2發布:新增全局搜索、播放器默認解碼方式等4大功能

EasyCVR視頻匯聚平臺帶著全新的v3.7.2版本重磅登場&#xff01;此次升級&#xff0c;絕非簡單的功能堆砌&#xff0c;而是從用戶體驗、操作效率以及系統性能等多維度進行的深度優化與革新&#xff0c;旨在為大家帶來更加強大、穩定且高效的視頻監控管理體驗。 一、全局功能搜索…

三、kubectl使用詳解

三、kubectl使用詳解 文章目錄 三、kubectl使用詳解1、常用基礎命令1.1 Kubectl命令格式1.2 查詢一個資源1.3 創建一個資源1.4 修改一個資源1.5 刪除一個資源1.6 其他 2、K8s隔離機制Namespace&#xff08;命名空間作用及使用&#xff09;2.1 什么是命名空間2.2 命名空間主要作…

JVM內存模型詳解

JVM內存模型詳解 Java虛擬機(JVM)內存模型是理解Java程序運行機制的核心&#xff0c;它定義了程序運行時數據的組織方式和訪問規則。與Java內存模型(JMM)關注并發不同&#xff0c;JVM內存模型主要描述運行時數據區的結構和功能。 一、JVM內存模型概述 JVM內存模型將運行時數…

《對話式 AI 白皮書》共創者招募

在 AI Agent 技術不斷演變的當下&#xff0c;共創一本不斷演變的對話式 AI 白皮書&#xff0c;共同探索人機對話的新紀元。無論你是開發者、技術專家、生態伙伴還是創業者&#xff0c;都期待你的加入。 項目地址&#xff1a;https://github.com/RTE-Dev/book_era_convoai/ 在…

Flux功能介紹,完整使用示例,與Mono對比

以下是關于Reactor框架中Flux與Mono的功能介紹、使用示例及對比分析&#xff1a; Flux功能介紹 核心定義 Flux是Reactor庫中的核心接口&#xff0c;表示一個異步的、包含零到多個元素的序列&#xff08;類似流式數據處理&#xff09;[3][4][7]。它可以處理無限長度的數據流&am…

Git使用基本指南

一、Git 基礎配置 首先需要配置用戶信息&#xff0c;讓 Git 知道你是誰&#xff1a; git config --global user.name "你的名字" git config --global user.email "你的郵箱example.com" 如果需要查看配置信息&#xff0c;可以使用&#xff1a; git co…

【入門】【例17.3】 內功逼毒

| 時間限制&#xff1a;C/C 1000MS&#xff0c;其他語言 2000MS 內存限制&#xff1a;C/C 64MB&#xff0c;其他語言 128MB 難度&#xff1a;中等 分數&#xff1a;100 OI排行榜得分&#xff1a;12(0.1分數2難度) 出題人&#xff1a;root | 描述 黃蓉中了毒&#xff0c;在 t 時…

蘋果芯片macOS安裝版Homebrew(親測)

在Linux服務器上安裝一個軟件常用yum&#xff0c;apt、dnf命令&#xff0c;同樣macOS可以使用brew命令來安裝軟件。 brew會自動幫你下載、解壓、安裝和配置&#xff0c;更重要的是&#xff1a;它還會自動處理好軟件之間的依賴關系&#xff0c;它將所有軟件都安裝在獨立的統一目…

uniapp+vue3做小程序,獲取容器高度

小程序獲能用createSelectorQuery&#xff0c;如果是子組件&#xff0c;后面可以額外加一個參數in來指定獲取dom的范圍。小程序里面可以直接.in(this)&#xff0c;但是vue3沒有this了&#xff0c;那就只能通過getCurrentInstance去獲取當前實例代替this &#xff0c;注意這里需…

【網工】華為配置專題進階篇①

目錄 ■浮動路由和BFD配置 ▲浮動路由 基本配置示例 ▲BFD ▲驗證命令 ▲測試連通性 ■路由綜合實驗RIP OSPF BGP ■浮動路由和BFD配置 ▲浮動路由 浮動路由&#xff1a;設置preference 浮動路由是一種備份路由機制&#xff0c;當主路由失效時&#xff0c;浮動路由會…

DeepLegal AI:智能法律文檔審查與合規助手+MVP

1. 商業價值與市場機會 DeepLegal AI旨在革新法律行業中耗時且資源密集型的文檔審查和合規流程。該應用將利用DeepSeek先進的語言模型能力&#xff0c;為律師事務所、企業法務部門和合規團隊提供一個高效、準確且經濟的解決方案。 市場機會&#xff1a; 法律科技市場正經歷爆…

使用 Rust 編寫簡單計算器

在編程語言的世界中&#xff0c;Rust 以其安全性和高性能而聞名。今天&#xff0c;我們將通過一個簡單的項目來探索 Rust 的魅力 —— 編寫一個簡單的命令行計算器。這個計算器將支持基本的算術運算&#xff08;加、減、乘、除&#xff09;&#xff0c;并且可以通過用戶輸入進行…

清華大學:《AI賦能教育 :高考志愿填報工具使用指南》下載

志愿填報的認知革命已經到來 “分數出來了&#xff0c;但不知道能上什么學校……” “喜歡這個專業&#xff0c;但不知道就業前景怎么樣&#xff1f;” “到底是選熱門專業還是選興趣愛好&#xff1f;” 這些讓百萬家庭徹夜難眠的問題&#xff0c;你是否正在經歷&#xff1f; …

【科技公司的管理】

如何打造高效、人性化的目標驅動型公司&#xff1f;——OKR管理法績效薪酬體系全指南 你希望公司目標清晰、員工高效、多勞多得&#xff0c;同時避免馬斯克式的“冷血管理”&#xff0c;兼顧員工生活需求。以下是系統性解決方案&#xff0c;涵蓋目標設定&#xff08;OKR&#x…

小白成長之路--nginx基礎配置(一)

文章目錄 一、概述1.1 Nginx 特點1.2 Nginx 作用1.3Nginx工作原理 二、Nginx服務搭建2.1安裝2.2 目錄結構2.3 配置文件作用2.4 nginx,conf配置文件詳解2.5 核心命令2.6 Nginx信號三.Nginx3.1啟動 總結 一、概述 Nginx 是開源、高性能、高可靠的 Web服務器 和反向代理服務器&am…

從最基礎的float布局開始學前端

前端學習其實不難&#xff0c;我們先從float布局講起&#xff0c;寫一個最簡單的導航欄&#xff1a;Logo在左&#xff0c;導航鏈接在右。下面是示例代碼&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"…

12. TypeScript 高級類型

TypeScript 中的高級類型包括映射類型、條件類型、字面量類型和遞歸類型等強大結構。這些特性使開發者能夠表達類型之間更復雜的關系&#xff0c;從而處理邊緣情況&#xff0c;并定義更動態、更靈活的類型系統。 一、映射類型 TypeScript 映射類型&#xff08;Mapped Types&a…

韓國證券交易所(KRX)全生態接入系統技術白皮書

核心價值&#xff1a;為全球最活躍的衍生品市場&#xff08;日均交易量480億美元&#xff09;提供 5μs延遲引擎全合規認證&#xff0c;助力中資機構搶占韓國78%衍生品交易份額 一、KRX市場機遇與準入壁壘 1.1 核心數據錨定&#xff08;2025Q2&#xff09; 指標數值全球競爭力…

【Clickhouse系列】增刪改查:對比mysql

目錄 1. 寫入操作 (INSERT) 2. 刪除操作 (DELETE) 3. 更新操作 (UPDATE) 4. 查詢操作 (SELECT) 5. 總結對比表&#xff1a; 6. 參考鏈接 核心哲學差異&#xff1a; MySQL&#xff1a; 面向在線事務處理。核心目標是保證數據的強一致性、原子性和低延遲的單行操作&#x…

低壓電工作業中,如何正確選用熔斷器的額定電流?

在低壓電工作業中&#xff0c;正確選用熔斷器額定電流需綜合考慮負載類型、額定電流等因素&#xff0c;具體方法如下&#xff1a; 照明電路&#xff1a;對于白熾燈負載&#xff0c;熔體額定電流可按被保護電路上所有白熾燈工作電流之和的 1.1 倍選取。若是日光燈和高壓水銀熒…