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

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

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

異常是每一個應用必須要處理的問題

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

在Controller寫一個異常

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

瀏覽器訪問:

用戶體驗相當不好,所以一般情況下,應用必須要想辦法處理異常。

異常處理方式

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

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

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

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

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

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

SpringMVC的異常處理

Spring MVC提供了如下異常處理選項:

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

@ExceptionHandle

@ExceptionHandle可以作用在Controller中,比如,在上面發(fā)生異常的Controller中增加一個@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 "錯了在helloworld Controller error msg is ===";
    }

運行:

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

問題解決了!

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

這樣的話,就需要對每一個Controller增加@ExceptionHandle進行處理,處理起來還是有點麻煩。

統(tǒng)一異常處理

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

@ControllerAdvice注解可以實現(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啟動的過程中,RequestMappingHandlerMapping和ExceptionHandlerExceptionResolver會檢測到advice bean并且在運行時會使用他們。在@ControllerAdvice中的@ExceptionHandler會變成一個全局的異常處理器、在本地異常處理器之后生效。并且,@ModelAttribute和 @InitBinder會在本地的之后生效。

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

這個工作是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;
    }

驗證一下。

加一個MyGlobalExceptionController:

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

先不去掉HelloWorldController中的異常處理器,運行hello:

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

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

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

自定義異常處理器HandlerExceptionResolver

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

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

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

相關文章

  • spring如何集成cxf實現(xiàn)webservice接口功能詳解

    spring如何集成cxf實現(xiàn)webservice接口功能詳解

    這篇文章主要給大家介紹了關于spring如何集成cxf實現(xiàn)webservice接口功能的相關資料,文中通過示例代碼介紹的非常詳細,對大家 的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧
    2018-07-07
  • Spring boot框架下的RabbitMQ消息中間件詳解

    Spring boot框架下的RabbitMQ消息中間件詳解

    這篇文章詳細介紹了Spring Boot框架下的RabbitMQ消息中間件的基本概念、消息傳輸模型、環(huán)境準備、Spring Boot集成以及消息生產(chǎn)和消費,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • JVM中的守護線程示例詳解

    JVM中的守護線程示例詳解

    這篇文章主要給大家介紹了關于JVM中守護線程的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-01-01
  • Spring中的代理ProxyFactory解析

    Spring中的代理ProxyFactory解析

    這篇文章主要介紹了Spring中的ProxyFactory解析,在Java中,代理模式的實現(xiàn)通常依靠Proxy類和InvocationHandler接口,本文將介紹如何使用ProxyFactory來創(chuàng)建代理模式,需要的朋友可以參考下
    2023-12-12
  • Java如何正確的使用wait-notify方法你知道嗎

    Java如何正確的使用wait-notify方法你知道嗎

    這篇文章主要為大家詳細介紹了Java如何正確的使用wait-notify方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • JAVA之String中刪除指定字符方式(11種方法)

    JAVA之String中刪除指定字符方式(11種方法)

    這篇文章主要介紹了JAVA之String中刪除指定字符方式(11種方法),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java使用遞歸復制文件夾及文件夾

    Java使用遞歸復制文件夾及文件夾

    這篇文章主要介紹了Java使用遞歸復制文件夾及文件夾,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • 通過Java代碼來創(chuàng)建view的方法

    通過Java代碼來創(chuàng)建view的方法

    本文給大家分享通過java代碼創(chuàng)建view的方法,以TextView為例創(chuàng)建控件的方法,需要的的朋友參考下吧
    2017-08-08
  • springBoot連接遠程Redis連接失敗的問題解決

    springBoot連接遠程Redis連接失敗的問題解決

    本文主要介紹了springBoot連接遠程Redis連接失敗的問題解決,使用springboot里面的redisTemplate進行連接的時候,卻發(fā)生了報錯,下面就來一起解決一下
    2024-05-05
  • HttpServletRequestWrapper干預Request處理流程解析

    HttpServletRequestWrapper干預Request處理流程解析

    這篇文章主要分析在?Tomcat的處理?http?請求的流程中干預?Request對象,?通過基于HttpServletRequestWrapper和?Filter組合進行干預,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-09-09

最新評論

姜堰市| 宜兴市| 东明县| 黎平县| 九江县| 密云县| 道孚县| 镇赉县| 五华县| 通州市| 涪陵区| 甘谷县| 盘山县| 武陟县| 铜梁县| 丽江市| 阳曲县| 南昌市| 厦门市| 镇平县| 饶平县| 定西市| 石景山区| 丽水市| 临清市| 邳州市| 张家川| 迁安市| 清涧县| 合阳县| 泽普县| 白河县| 南川市| 泰顺县| 大丰市| 盈江县| 洪雅县| 界首市| 谢通门县| 庆阳市| 贺州市|