環(huán)境:Springboot3.0.5
概述如果在請求映射期間發(fā)生異常或從請求處理程序(例如@Controller)拋出異常,DispatcherServlet將委托給HandlerExceptionResolver
(資料圖片僅供參考)
下表列出了可用的HandlerExceptionResolver實現(xiàn)。
HandlerExceptionResolver實現(xiàn)類:
HandlerExceptionResolver | 描述 |
SimpleMappingExceptionResolver | 異常類名和錯誤視圖名之間的映射。用于在瀏覽器應用程序中渲染錯誤頁面。 |
DefaultHandlerExceptionResolver | 解析Spring MVC引發(fā)的異常,并將其映射為HTTP狀態(tài)碼。 |
ResponseStatusExceptionResolver | 使用@ResponseStatus注解解析異常,并根據(jù)注解中的值將異常映射為HTTP狀態(tài)碼。 |
ExceptionHandlerExceptionResolver | 通過在@Controller或@ControllerAdvice類中調(diào)用由@ExceptionHandler注釋的方法來解決異常。 |
我們可以聲明多個HandlerExceptionResolver
HandlerExceptionResolver的約定規(guī)定它可以返回:
指向錯誤視圖的ModelAndView。如果異常是在解析器中處理的,則返回空的ModelAndView。如果異常仍然未解決,則為null,以便后續(xù)的解析器嘗試,如果異常在最后仍然存在,則允許它向上冒泡到Servlet容器。Controller接口調(diào)用原理SpringMVC請求入口通過DispatcherServlet執(zhí)行大致核心流程如下:
首先通過HandlerMapping確定目標Handler對象(如果接口是Controller那么這里會是HandlerMethod)通過上一步Handler對象,確定執(zhí)行真正調(diào)用的HandlerAdapter這里以Controller接口為例,HandlerAdapter對象為RequestMappingHandlerAdapter
DispatcherServletpublic class DispatcherServlet extends FrameworkServlet { protected void doDispatch(...) throws Exception { HandlerExecutionChain mappedHandler = null; try { Exception dispatchException = null; // 根據(jù)請求確定Handler對象(遍歷所有的HandlerMapping) mappedHandler = getHandler(processedRequest); // 根據(jù)上一步確定的Handler對象,確定HandlerAdapter對象 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 真正執(zhí)行目標方法的調(diào)用 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { dispatchException = new ServletException("Handler dispatch failed: " + err, err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); }}RequestMappingHandlerAdapterpublic class RequestMappingHandlerAdapter { protected ModelAndView handleInternal(...) throws Exception { ModelAndView mav; mav = invokeHandlerMethod(request, response, handlerMethod); } protected ModelAndView invokeHandlerMethod(...) throws Exception { // ... ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod); // ... 對ServletInvocableHandlerMethod進行配置 invocableMethod.invokeAndHandle(webRequest, mavContainer); return getModelAndView(mavContainer, modelFactory, webRequest); }}ServletInvocableHandlerMethod執(zhí)行參數(shù)解析目標Controller方法調(diào)用及返回值的處理
public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { public void invokeAndHandle(...) throws Exception { // 該方法中會進行請求參數(shù)的解析及目標方法的調(diào)用 Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); // ... try { // 處理返回值 this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception ex) { throw ex; } }}通過上面的源碼分析,在調(diào)用過程中如果發(fā)生了異常會將異常直接拋出,在DispatcherServlet中會進行異常的處理。
異常解析原理分析接著上面的源碼分析,當發(fā)生異常后最終會在DispatcherServlet#processDispatchResult方法中進行處理。
public class DispatcherServlet extends FrameworkServlet { /* * 默認情況下有如下2個異常解析器 * 1. DefaultErrorAttributes * 2. ExceptionHandlerExceptionResolver */ private List handlerExceptionResolvers; private void processDispatchResult(...) { if (exception != null) { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); // 處理異常 mv = processHandlerException(request, response, handler, exception); } } protected ModelAndView processHandlerException(...) throws Exception { ModelAndView exMv = null; if (this.handlerExceptionResolvers != null) { // 遍歷所有的異常解析器 for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) { // 解析異常,核心的解析器是ExceptionHandlerExceptionResolver exMv = resolver.resolveException(request, response, handler, ex); } } // ... }} ExceptionHandlerExceptionResolver類繼承自AbstractHandlerMethodExceptionResolver該類又繼承自AbstractHandlerExceptionResolver
// 調(diào)用父類(AbstractHandlerExceptionResolver)方法public abstract class AbstractHandlerExceptionResolver implements HandlerExceptionResolver, Ordered { public ModelAndView resolveException(...) { // doResolveException該方法在子類AbstractHandlerMethodExceptionResolver中重寫 ModelAndView result = doResolveException(request, response, handler, ex); }}AbstractHandlerMethodExceptionResolver
public abstract class AbstractHandlerMethodExceptionResolver extends AbstractHandlerExceptionResolver { protected final ModelAndView doResolveException(...) { HandlerMethod handlerMethod = (handler instanceof HandlerMethod hm ? hm : null); return doResolveHandlerMethodException(request, response, handlerMethod, ex); }}ExceptionHandlerExceptionResolver
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver implements ApplicationContextAware, InitializingBean { protected ModelAndView doResolveHandlerMethodException(...) { // 該方法中會先從當前的Controller中查找是否有@ExceptionHandler注解的方法(如果匹配) // 如果沒有再從全局的異常處理類句柄中查找 ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception); if (exceptionHandlerMethod == null) { return null; } // 執(zhí)行異常處理方法的調(diào)用 exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, arguments); } protected ServletInvocableHandlerMethod getExceptionHandlerMethod(...) { Class> handlerType = null; if (handlerMethod != null) { handlerType = handlerMethod.getBeanType(); // 緩存并設置當前執(zhí)行Class對應的ExceptionHandlerMethodResolver // ExceptionHandlerMethodResolver構(gòu)造函數(shù)中會解析當前類中的所有方法是否有@ExceptionHandler注解 ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.computeIfAbsent(handlerType, ExceptionHandlerMethodResolver::new); // 解析是否匹配當前發(fā)生的異常 Method method = resolver.resolveMethod(exception); if (method != null) { return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method, this.applicationContext); } } // 如果上面的執(zhí)行的Class中沒有找到對應處理器,那么就從全局的異常處理中進行查找匹配 // 這里的exceptionHandlerAdviceCache集合在類初始化執(zhí)行時已經(jīng)處理完成 for (Map.Entry entry : this.exceptionHandlerAdviceCache.entrySet()) { ControllerAdviceBean advice = entry.getKey(); if (advice.isApplicableToBeanType(handlerType)) { ExceptionHandlerMethodResolver resolver = entry.getValue(); Method method = resolver.resolveMethod(exception); if (method != null) { return new ServletInvocableHandlerMethod(advice.resolveBean(), method, this.applicationContext); } } } return null; }} 通過上面的源碼分析你應該知道了關(guān)于SpringMVC中異常處理的原理。
當上面的異常處理機制都沒法處理,那么將會調(diào)用默認的/error接口。
public class ErrorMvcAutoConfiguration { @Bean @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT) public BasicErrorController basicErrorController(ErrorAttributes errorAttributes, ObjectProvider errorViewResolvers) { return new BasicErrorController(errorAttributes, this.serverProperties.getError(), errorViewResolvers.orderedStream().toList()); } } BasicErrorController@Controller@RequestMapping("${server.error.path:${error.path:/error}}")public class BasicErrorController extends AbstractErrorController {}上面的錯誤接口/error在容器啟動時會自動注冊到內(nèi)嵌的容器中,如:Tomcat。
標簽:
詳解SpringBoot接口異常處理機制及源碼分析_今日精選 環(huán)境:Springboot3 0 5概述如果在請求映射期間發(fā)生異常或從請求處理程
電報解讀|AI促光通信產(chǎn)業(yè)高速發(fā)展 薄膜鈮酸鋰潛在市場空間接近百億 精品VIP投研內(nèi)容
西湖劃船刺客運營方被罰12萬 西湖“劃船刺客”事件最新進展! 近日,杭州西湖風景名勝區(qū)國有資本投資運營有限公司因消費侵權(quán)行為,被
佐力藥業(yè)(300181.SZ):2022年度烏靈系列營業(yè)收入達10.92億元|全球熱頭條 格隆匯6月15日丨佐力藥業(yè)300181300181SZ召開線上會議就烏靈系列的收入
拼多多客服賬號怎么進行創(chuàng)建?拼多多客服外包平臺怎么加入? 拼多多客服賬號怎么進行創(chuàng)建?登錄拼后臺點擊設置子賬號管理,在右
詳解SpringBoot接口異常處理機制及源碼分析_今日精選 環(huán)境:Springboot3 0 5概述如果在請求映射期間發(fā)生異常或從請求處理程
木雕、磚雕、面具、唐卡……尼泊爾手工藝品展亮相三亞 近日,第三屆南山非遺節(jié)正在三亞南山文化旅游區(qū)火熱進行中,海南省非遺
火星報創(chuàng)辦時間什么時候?火星報創(chuàng)辦背景是什么? 火星報創(chuàng)辦時間什么時候?1900年12月24日,火星報是由列寧領(lǐng)導的,俄
理財沒到期急用錢怎么辦?錢存了理財沒到期可以取出來嗎? 每日速看 在理財過程中,有時候投資者可能會遇到緊急的資金需求,而此時投資
環(huán)球熱推薦:瓊港新企業(yè)交流中心落戶三亞 6月13日,海南自由貿(mào)易港(三亞)新加坡投資交流會在新加坡舉行,市投
5萬級超高性價比小車,瑞虎3x拼多多專屬電商版上線,價格一卷到底 通過電商平臺購買汽車產(chǎn)品,已成為年輕人喜聞樂見的消費形式,而汽車廠商也都樂于攜手電商平臺,以更多的實惠和驚喜,來提升用戶的消費和服
京東物流落成全球規(guī)模最大倉揀一體智能物流園區(qū) 一箱剛從蘇州蟹塘現(xiàn)捕現(xiàn)撈的“六月黃”(臨近成熟的大閘蟹)14日從京東物
電動皮卡 怎么突然就行了? 全球快訊 電動皮卡怎么突然就行了?
高速錯過出口 豐田亞洲龍緩行被大貨車追尾致5死 官方:兩司機均分心駕駛-環(huán)球簡訊 高速錯過出口豐田亞洲龍緩行被大貨車追尾致5死官方:兩司機均分心駕駛
極萌Jmoon帶來變美科技新革命 極萌Jmoon,作為一家專注于極速美容科技的公司,一直在持續(xù)進行著市場調(diào)研和技術(shù)創(chuàng)新。重視產(chǎn)品的質(zhì)量和行業(yè)標準,致力于推動行業(yè)朝著標準
茶杯犬一歲等于人的幾歲? 茶杯犬的缺點有哪些?_最新資訊 現(xiàn)在很多家庭都會養(yǎng)寵物,而小狗就是家庭寵物的選擇之一,狗的品種
FOF基金有什么優(yōu)勢?私募基金和公募基金誰收益更高? FOF基金有什么優(yōu)勢?1 解決基金產(chǎn)品篩選難題。目前國內(nèi)公募基金數(shù)量
香瓜種植時間和方法是什么?香瓜熱量高嗎減肥期間能吃嗎?-世界播資訊 香瓜種植時間和方法是什么?香瓜的種植時間是每年的8~10月份。香瓜種
焦點熱文:三亞建立“熱線+督查+制度” 三位一體破難題機制 日前,三亞多部門聯(lián)合下發(fā)《關(guān)于建立“熱線+督查+制度”三位一體同推互
選址日報:三星投215億建生產(chǎn)基地;諾和諾德斥164億擴建工廠 三星投215億建生產(chǎn)基地據(jù)最新消息,三星旗下負責電池和電子材料制造的
天天亮點!裝700件快遞大貨車高速爆胎翻車 車輪花紋都磨沒了 裝700件快遞大貨車高速爆胎翻車車輪花紋都磨沒了
熱訊:小米14設計定了:標準版小直屏 Pro版極窄微曲屏 (相關(guān)資料圖)6月15日消息,高通今年的驍龍技術(shù)峰會提前到10月份,這
三亞劃定21個城市更新片區(qū) 以天涯區(qū)和吉陽區(qū)的老城片區(qū)為主_天天熱點評 日前,《三亞市中心城區(qū)城市更新專項規(guī)劃》(以下簡稱《規(guī)劃》)出爐,
基金定投選擇哪種基金?基金存在的風險有哪些? 基金定投應該選擇什么樣的基金?1 波動大基金定投的收益主要是通過微
時訊:背書轉(zhuǎn)讓的限制主要有哪些?背書轉(zhuǎn)讓具有哪些法律效力? 背書轉(zhuǎn)讓的限制主要有哪些?(1)出票人在匯票上記載不得轉(zhuǎn)讓字樣的,
每日看點!“期待更多有志青年返鄉(xiāng)創(chuàng)業(yè)”(幫扶縣駐村手記) 走進河南省商丘市虞城縣大侯鎮(zhèn)聶樓村產(chǎn)業(yè)園的一家箱包廠,敞亮的車間里
谷歌推出多項功能:識別皮膚病、模擬試穿衣服
當前視點 IT之家6月15日消息,谷歌近日宣布了一系列新的搜索更新,涵蓋了旅游規(guī)
5萬級超高性價比小車,瑞虎3x拼多多專屬電商版上線,價格一卷到底 通過電商平臺購買汽車產(chǎn)品,已成為...
天貓國際支付方式有云閃付嗎?天貓國際用戶購買須知是啥意思? 天貓國際支付方式有云閃付嗎?有一...
極萌Jmoon帶來變美科技新革命 極萌Jmoon,作為一家專注于極速美...
木雕、磚雕、面具、唐卡……尼泊爾手工藝品展亮相三亞 近日,第三屆南山非遺節(jié)正在三亞南...
清淤疏浚 改善水質(zhì) 6月14日,在三亞河上,工作人員正...
環(huán)球熱推薦:瓊港新企業(yè)交流中心落戶三亞 6月13日,海南自由貿(mào)易港(三亞)...
焦點熱文:三亞建立“熱線+督查+制度” 三位一體破難題機制 日前,三亞多部門聯(lián)合下發(fā)《關(guān)于建...
膏藥代加工發(fā)展迎來新機遇 仙佑集團質(zhì)量嚴把關(guān)受關(guān)注-天天即時 作為國內(nèi)知名的膏藥代加工企業(yè)之一...
互聯(lián)網(wǎng)+醫(yī)療助力研發(fā)投入 鄭州膏藥代加工保障質(zhì)量安全 作為國內(nèi)知名的膏藥代加工企業(yè)之一...
斥資226億元,TI將在馬來西亞新建兩座工廠 6月13日,德州儀器(TI)宣布將在...
互聯(lián)網(wǎng)+醫(yī)療助力研發(fā)投入 鄭州膏藥代加工保障質(zhì)量安全 作為國內(nèi)知名的膏藥代加工企業(yè)之一...
不良信用記錄包括什么?不良信用記錄幾年可以消除?-全球即時看 不良信用記錄包括什么?不良信用記...
騰訊有意全資收購搜狗 王小川是怎么回應的? 天天觀察 騰訊有意全資收購搜狗搜狗公告顯示...
天天百事通!提取約翰?列儂聲音 披頭士借助AI發(fā)行最后一曲 (相關(guān)資料圖)據(jù)BBC報道,即將迎來8...
為困境未成年人提供家庭教育指導 為了促進家庭教育的科學化、規(guī)范化...
今亮點!只要錢夠多 哪怕危險行業(yè)獅子座也會勇敢嘗試? 金牛座:錢是最重要的金牛座是出了...
世界今亮點!徐州泉山:“微改造”助力“大文明” “微環(huán)境”塑造“微幸福” “今天好開心,我連闖三關(guān)!”近日...
全球信息:散戶和機構(gòu)投資者的資金實力一樣嗎?散戶和機構(gòu)投資者的作用一樣嗎? 散戶和機構(gòu)投資者的資金實力一樣嗎...
荷蘭豬的壽命有多長 ?荷蘭豬簡介_當前熱議 荷蘭豬其實指的就是豚鼠,又叫天竺...
環(huán)球速訊:退休后如何存錢收益高?老年人怎么理財合適? 很多老人退休后喜歡做資產(chǎn)規(guī)劃,如...
環(huán)球觀天下!倉鼠懷孕了怎么辦?倉鼠懷孕有什么特征呢? 大部分人都有養(yǎng)小倉鼠的經(jīng)歷吧,倉...
天天通訊!整存整取起存金額多少 ?整存整取可以提前取嗎? 銀行定期存款包括整存整取、整存零...
臨近抄底現(xiàn)象是什么(股票抄底是什么意思)|當前通訊 臨近抄底現(xiàn)象是什么(散戶為什么喜...
國家統(tǒng)計局:1-5月商品房銷售額同比增長8.4% 6月15日,國家統(tǒng)計局發(fā)布了1-5月份...
房屋保險一年多少錢?房屋保險怎么買劃算? 房屋保險一年多少錢?不同的產(chǎn)品自...
熱點聚焦:膏藥謀求高質(zhì)量發(fā)展 河南仙佑膏藥代加工產(chǎn)業(yè)升級 作為國內(nèi)知名的膏藥代加工企業(yè)之一...
膏藥謀求高質(zhì)量發(fā)展 河南仙佑膏藥代加工產(chǎn)業(yè)升級 作為國內(nèi)知名的膏藥代加工企業(yè)之一...
招商銀行周周寶贖回幾天到賬?招行理財利率是多少? 焦點關(guān)注 現(xiàn)在各大銀行也相繼推出了很多理財...
天貓國際支付方式有云閃付嗎?天貓國際用戶購買須知是啥意思? 天貓國際支付方式有云閃付嗎?有一...
世界新消息丨真刑!借“總部經(jīng)濟”之名,開709家空殼公司,偽裝產(chǎn)業(yè)集群 正義網(wǎng)近日披露了一宗借“總部經(jīng)濟...
整合旗下國有投資平臺 杭州打出“3000億產(chǎn)業(yè)基金集群”王牌 環(huán)球報道 又一個千億母基金群來了。今日,杭...
合金彈頭如何調(diào)節(jié)靈敏度?合金彈頭速度太快怎么調(diào)?|新消息 合金彈頭如何調(diào)節(jié)靈敏度?打開游戲...
理財產(chǎn)品工作日可申贖是什么意思?申贖和買賣有什么區(qū)別?|世界看點 購買理財產(chǎn)品的時候,投資者會看理...
隔夜回購操作是什么意思?隔日回購協(xié)議的基本內(nèi)容是什么? 隔夜回購操作是什么意思?隔夜回購...
焦點短訊!谷歌將生成式 AI 應用于在線購物,真人模特可實現(xiàn)高精度虛擬換衣
IT之家6月15日消息,谷歌昨日宣布...