欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringMVC使用@ExceptionHandler注解在Controller中處理異常

 更新時(shí)間:2023年10月12日 11:35:04   作者:福  
這篇文章主要為大家介紹了SpringMVC使用@ExceptionHandler注解在Controller中處理異常示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

異常是每一個(gè)應(yīng)用必須要處理的問題

Spring MVC項(xiàng)目,如果不做任何的異常處理的話,發(fā)生異常后,異常堆棧信息會(huì)直接拋出到頁面。

在Controller寫一個(gè)異常

@GetMapping(value="/hello",produces={"text/html; charset=UTF-8"})
    @ResponseBody
    public String hello(ModelAndView model){
        int c = 100 / 0;
        return "<h1>User info</h1>";
    }

瀏覽器訪問:

用戶體驗(yàn)相當(dāng)不好,所以一般情況下,應(yīng)用必須要想辦法處理異常。

異常處理方式

常見的異常處理方式,無非:

  • 應(yīng)用中對(duì)所有可能發(fā)生異常的地方,都try catch,捕獲異常后做相應(yīng)的處理。
  • 集中處理異常。

第一種方式顯然不好,一方面是代碼中需要到處都寫try catch,萬一某一段代碼由于程序員的疏忽沒有寫,異常就會(huì)拋出到前臺(tái),很不好。

另外,某些情況下異常是不能捕獲的,比如需要事務(wù)處理的代碼,捕獲異常后會(huì)影響到事務(wù)回滾。

所以,我們還是需要想辦法用第2中方式來處理異常。n多年前曾經(jīng)做過一個(gè)摩托羅拉的項(xiàng)目,其中一項(xiàng)需求就是對(duì)一個(gè)線上系統(tǒng)的異常做處理、不允許異常信息拋出到前臺(tái)頁面。當(dāng)初那個(gè)項(xiàng)目并沒有采用類似SpringMVC的框架,所以最終提出了用filter、在filter中攔截異常的處理方案并且被客戶采納。

其實(shí)SpringMVC的統(tǒng)一異常處理方案和我上面項(xiàng)目中采用的方案非常類似。

SpringMVC的異常處理

Spring MVC提供了如下異常處理選項(xiàng):

  • @ExceptionHandle
  • @ExceptionHandle + @ControllerAdvice
  • 自定義異常處理器HandlerExceptionResolver

@ExceptionHandle

@ExceptionHandle可以作用在Controller中,比如,在上面發(fā)生異常的Controller中增加一個(gè)@ExceptionHandle注解的方法:

@GetMapping(value="/hello",produces={"text/html; charset=UTF-8"})
    @ResponseBody
    public String hello(ModelAndView model){
        int c = 100 / 0;
        return "<h1>User info</h1>";
    }
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handle(Exception ex){
        return "錯(cuò)了在helloworld Controller error msg is ===";
    }

運(yùn)行:

說明Hello方法中發(fā)生的異常,已經(jīng)被handle方法處理,前臺(tái)頁面不再會(huì)出現(xiàn)異常信息。

問題解決了!

但是@ExceptionHandle只在當(dāng)前Controller文件中生效,也就是說,當(dāng)前Controller中的方法、或者方法調(diào)用的service層、dao層等發(fā)生的異常,才會(huì)被捕獲到。其他Controller中發(fā)生的異常依然不會(huì)被捕獲。

這樣的話,就需要對(duì)每一個(gè)Controller增加@ExceptionHandle進(jìn)行處理,處理起來還是有點(diǎn)麻煩。

統(tǒng)一異常處理

@ExceptionHandle + @ControllerAdvice可以實(shí)現(xiàn)統(tǒng)一異常處理。

@ControllerAdvice注解可以實(shí)現(xiàn):

On startup, RequestMappingHandlerMapping and ExceptionHandlerExceptionResolver detect controller advice beans and apply them at runtime. Global @ExceptionHandler methods, from an @ControllerAdvice, are applied after local ones, from the @Controller. By contrast, global @ModelAttribute and @InitBinder methods are applied before local ones.

SpringMVC啟動(dòng)的過程中,RequestMappingHandlerMapping和ExceptionHandlerExceptionResolver會(huì)檢測(cè)到advice bean并且在運(yùn)行時(shí)會(huì)使用他們。在@ControllerAdvice中的@ExceptionHandler會(huì)變成一個(gè)全局的異常處理器、在本地異常處理器之后生效。并且,@ModelAttribute和 @InitBinder會(huì)在本地的之后生效。

這段話的意思就是,@ExceptionHandle + @ControllerAdvice之后,@ExceptionHandle就會(huì)變成全局異常處理器。所謂的本地異常處理器,就是寫在Controller中的@ExceptionHandle異常處理器。

這個(gè)工作是ExceptionHandlerExceptionResolver干的,源碼中可以看到:

@Nullable
    protected ServletInvocableHandlerMethod getExceptionHandlerMethod(
            @Nullable HandlerMethod handlerMethod, Exception exception) {
        Class<?> handlerType = null;
        //先找"local"異常處理器
        if (handlerMethod != null) {
            // Local exception handler methods on the controller class itself.
            // To be invoked through the proxy, even in case of an interface-based proxy.
            handlerType = handlerMethod.getBeanType();
            ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType);
            if (resolver == null) {
                resolver = new ExceptionHandlerMethodResolver(handlerType);
                this.exceptionHandlerCache.put(handlerType, resolver);
            }
            Method method = resolver.resolveMethod(exception);
            if (method != null) {
                return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method);
            }
            // For advice applicability check below (involving base packages, assignable types
            // and annotation presence), use target class instead of interface-based proxy.
            if (Proxy.isProxyClass(handlerType)) {
                handlerType = AopUtils.getTargetClass(handlerMethod.getBean());
            }
        }
        //再找advice的異常處理器
        for (Map.Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> 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);
                }
            }
        }
        return null;
    }

驗(yàn)證一下。

加一個(gè)MyGlobalExceptionController:

@ControllerAdvice
public class MyGlobalExceptionController {
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handle(Exception ex){
        return return "錯(cuò)了MyGlobalExceptionController error msg is ===";
    }
}

先不去掉HelloWorldController中的異常處理器,運(yùn)行hello:

生效的是HelloWorldController中的異常處理器。

然后去掉HelloWorldController中的異常處理器:

寫在MyGlobalExceptionController中的全局異常處理器生效!

自定義異常處理器HandlerExceptionResolver

實(shí)現(xiàn)接口HandlerExceptionResolver,或者擴(kuò)展虛擬類AbstractHandlerMethodExceptionResolver(勉強(qiáng)可以考慮),定義自己的異常處理器。

其實(shí),非必要(沒想到有什么必要性)不建議!

以上就是SpringMVC使用@ExceptionHandler注解在Controller中處理異常的詳細(xì)內(nèi)容,更多關(guān)于SpringMVC異常處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • idea安裝漢化插件的圖文教程

    idea安裝漢化插件的圖文教程

    本文主要介紹了idea安裝漢化插件的圖文教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 新手了解java 異常處理基礎(chǔ)知識(shí)

    新手了解java 異常處理基礎(chǔ)知識(shí)

    Java中異常提供了一種識(shí)別及響應(yīng)錯(cuò)誤情況的一致性機(jī)制,有效地異常處理能使程序更加健壯、易于調(diào)試。那么這篇文章總結(jié)了Java有效處理異常的三個(gè)原則,有需要的朋友們可以參考借鑒
    2021-07-07
  • Springboot集成規(guī)則引擎Drools方式

    Springboot集成規(guī)則引擎Drools方式

    這篇文章主要介紹了Springboot集成規(guī)則引擎Drools方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • java時(shí)間戳轉(zhuǎn)換為日期格式的多種方式

    java時(shí)間戳轉(zhuǎn)換為日期格式的多種方式

    本文介紹了五種將Java時(shí)間戳轉(zhuǎn)換為日期格式的方法,包括使用Date類、LocalDateTime類、Instant類、DateUtils類以及自定義時(shí)區(qū),每種方法都有其適用場(chǎng)景,可以根據(jù)具體需求選擇合適的方法,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Java實(shí)現(xiàn)導(dǎo)出Excel功能

    Java實(shí)現(xiàn)導(dǎo)出Excel功能

    通過java中Controller層,來接受請(qǐng)求,數(shù)據(jù)庫查詢到的數(shù)據(jù)進(jìn)行封裝,然后使用ExcelUtils進(jìn)行輸出,接下來通過本文給大家分享Java實(shí)現(xiàn)導(dǎo)出Excel功能的實(shí)例代碼,感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • Java中的WeakHashMap源碼分析

    Java中的WeakHashMap源碼分析

    這篇文章主要介紹了Java中的WeakHashMap源碼分析,WeakHashMap可能平時(shí)使用的頻率并不高,但是你可能聽過WeakHashMap會(huì)進(jìn)行自動(dòng)回收吧,下面就對(duì)其原理進(jìn)行分析,需要的朋友可以參考下
    2023-09-09
  • Java多線程Callable接口實(shí)現(xiàn)代碼示例

    Java多線程Callable接口實(shí)現(xiàn)代碼示例

    相信大家對(duì)Java編程中如何創(chuàng)建線程已經(jīng)不陌生了,這篇文章就向朋友們介紹實(shí)現(xiàn)callable接口,具體實(shí)例詳見正文。
    2017-10-10
  • Windows編寫jar啟動(dòng)腳本和關(guān)閉腳本的操作方法

    Windows編寫jar啟動(dòng)腳本和關(guān)閉腳本的操作方法

    腳本文件,通常放入/bin目錄下,編寫啟動(dòng)腳本需要保證能夠識(shí)別到對(duì)應(yīng)的jar文件,其次需要保證能夠識(shí)別到/config中的配置文件信息,這篇文章主要介紹了Windows編寫jar啟動(dòng)腳本和關(guān)閉腳本的操作方法,需要的朋友可以參考下
    2022-12-12
  • mybatis查詢實(shí)現(xiàn)返回List<Map>類型數(shù)據(jù)操作

    mybatis查詢實(shí)現(xiàn)返回List<Map>類型數(shù)據(jù)操作

    這篇文章主要介紹了mybatis查詢實(shí)現(xiàn)返回List<Map>類型數(shù)據(jù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java并發(fā)編程進(jìn)階之線程控制篇

    Java并發(fā)編程進(jìn)階之線程控制篇

    在使用Java實(shí)際編程中,多線程可以說是無所不在,凡是需要并發(fā)執(zhí)行的都可以用到它,一個(gè)應(yīng)用程序中不用多線程將會(huì)是很糟糕的事情,所以掌握線程以及它的控制操作是非常重要的。通過本篇文章來今天帶大家一文掌握線程控制操作,感謝您的觀看
    2022-07-07

最新評(píng)論