dubbo和spring mvc全局異常處理器實(shí)現(xiàn)

spring mvc 的全局異常處理器

@ExceptionHandler
當(dāng)它在一個 controller 內(nèi)部聲明時业踏,它將被用于那個controller(或它的子類)的 @RequestMapping方法拋出的異常. 你也可以在 @ControllerAdvice 類里面聲明 @ExceptionHandler 方法,它將會處理很多controller的 @RequestMapping方法拋出的異常. 我的例子就是寫一個異常處理類彻犁,其被@ControllerAdvice注解玄帕。
例如:

@ControllerAdvice
public class BizExceptionFilter implements Filter {
  @ExceptionHandler(value = Exception.class)
  public Object handleIOException(Exception e){
    log.info("Catch exception", e);
    String exceptionName=e.getClass().getName();
    ResultExceptionInfoBean resultExceptionInfoBean=getInfoBean(exceptionName);
    FResponse rsp = new FResponse<Object>();
    rsp.setCode(resultExceptionInfoBean.getCode());
    rsp.setMessage(resultExceptionInfoBean.getMessage());
    rsp.setData(e);
    return rsp;
  }

@ExceptionHandler 的value可以設(shè)置一個需要被處理的異常數(shù)組. 如果一個異常被拋出并且包含在這個異常列表中, 然后就會調(diào)用 @ExceptionHandler 方法. 如果沒有設(shè)置value义锥,
那么就會使用參數(shù)里面的異常.
和標(biāo)準(zhǔn)controller的 @RequestMapping 方法很相似, @ExceptionHandler 方法的參數(shù)值和返回值相當(dāng)靈活. 比如說, HttpServletRequest 可以在 Servlet 環(huán)境中被接收, PortletRequest 在 Portlet 環(huán)境中被接收. 返回值可以是 String, 它將解釋為一個視圖, 可以是 ModelAndView 對象, 可以是 ResponseEntity 對象, 或者你可以添加 @ResponseBody 方法直接返回消息.

dubbo的異常處理

由于spring 的全局異常處理只能對http請求有效,所以對于dubbo的調(diào)用不起作用饱搏。

那么為了實(shí)現(xiàn)對dubbo調(diào)用異常的處理究反,我們可以使用dubbo的攔截擴(kuò)展.
具體配置方式詳見 API.
將擴(kuò)展方法寫到spring 的全局異常處理器中,使其繼承Filter舟奠,然后配置服務(wù)方調(diào)用攔截。
當(dāng)服務(wù)被調(diào)用時就會執(zhí)行該方法房维。
例如:

 @ControllerAdvice
public class BizExceptionFilter implements Filter {

@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
    log.debug("BizExceptionFilter:{},{}", invoker.getInterface(),
    JsonUtil.jsonFromObject(invocation.getArguments()));
    Result result = invoker.invoke(invocation);
    Object realResult = result.getValue();
    FResponse rsp = new FResponse<Object>();
    if (result.hasException()) {
      try {
        ExceptionHandlerMethodResolver resolver=new   ExceptionHandlerMethodResolver(this.getClass());
        Exception exception=(Exception) result.getException();
        Method method=resolver.resolveMethod(exception);
        realResult = method.invoke(this, exception);

        return new RpcResult(realResult);
      } catch (Throwable e) {
        log.error("Exception handler error. Caused Exception:{}", result.getException());
      }
    }
    rsp.setCode("0000");
    rsp.setMessage("Success");
    rsp.setData(realResult);
    return new RpcResult(rsp);
    }

  @ExceptionHandler(value = NullPointerException.class)
  public Object handleIOException(NullPointerException e){
    log.info("Catch exception", e);
    String exceptionName=e.getClass().getName();
    ResultExceptionInfoBean resultExceptionInfoBean=getInfoBean(exceptionName);
    FResponse rsp = new FResponse<Object>();
    rsp.setCode(resultExceptionInfoBean.getCode());
    rsp.setMessage(resultExceptionInfoBean.getMessage());
    rsp.setData(e);
    return rsp;
  }
  @ExceptionHandler(value = IndexOutOfBoundsException.class)
  public Object handleIOException(IndexOutOfBoundsException e){
    log.info("Catch exception", e);
    String exceptionName=e.getClass().getName();
    ResultExceptionInfoBean resultExceptionInfoBean=getInfoBean(exceptionName);
    FResponse rsp = new FResponse<Object>();
    rsp.setCode(resultExceptionInfoBean.getCode());
    rsp.setMessage(resultExceptionInfoBean.getMessage());
    rsp.setData(e);
    return rsp;
  }

解析:
Result result = invoker.invoke(invocation);這行代碼之前的代碼沼瘫,是在服務(wù)被調(diào)用錢執(zhí)行,之后的代碼是在服務(wù)被調(diào)用后執(zhí)行咙俩。

Object realResult = result.getValue();獲得執(zhí)行結(jié)果.

result.hasException()是否拋出了異常.

A912450C-D6D7-4E83-85E4-12034B2569B4.png
這段代碼就是利用反射機(jī)制耿戚,獲得當(dāng)前的類的方法,然后調(diào)用該對象的有exception參數(shù)的方法阿趁,并將結(jié)果返回溅话。

2017-3-15 更新
Exception exception=(Exception) result.getException(); 這行代碼的作用是獲得此類中被@ExceptionHandler注解的方法。
Method method=resolver.resolveMethod(exception);這行代碼的作用是從被@ExceptionHandler注解的所有方法中找出value為exception的方法對象歌焦。
realResult = method.invoke(this, exception); 執(zhí)行這個方法飞几。
如圖:

6D14283E-035B-443E-9FDA-276DA93643AB.png

這樣保持了和spring 的全局異常處理一致,即被@ExceptionHandler注解的方法去處理異常。
spring 相關(guān)源碼如下:
Paste_Image.png

測試:
我在服務(wù)類中直接拋出了異常独撇。

8EB375E9-8266-4A82-BD85-0FD9BFEC085F.png

順利執(zhí)行:

CB3B887D-FB1D-432B-A9CA-150FE7E3E93C.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屑墨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纷铣,更是在濱河造成了極大的恐慌卵史,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搜立,死亡現(xiàn)場離奇詭異以躯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)啄踊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門忧设,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颠通,你說我怎么就攤上這事址晕。” “怎么了顿锰?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵谨垃,是天一觀的道長。 經(jīng)常有香客問我硼控,道長刘陶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任牢撼,我火速辦了婚禮匙隔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浪默。我一直安慰自己牡直,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布纳决。 她就那樣靜靜地躺著碰逸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪阔加。 梳的紋絲不亂的頭發(fā)上饵史,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音胜榔,去河邊找鬼胳喷。 笑死,一個胖子當(dāng)著我的面吹牛夭织,可吹牛的內(nèi)容都是我干的吭露。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尊惰,長吁一口氣:“原來是場噩夢啊……” “哼讲竿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起弄屡,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤题禀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后膀捷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迈嘹,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年全庸,在試婚紗的時候發(fā)現(xiàn)自己被綠了秀仲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡壶笼,死狀恐怖啄育,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拌消,我是刑警寧澤挑豌,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站墩崩,受9級特大地震影響氓英,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹦筹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一铝阐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铐拐,春花似錦徘键、人聲如沸练对。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽螟凭。三九已至,卻和暖如春它呀,著一層夾襖步出監(jiān)牢的瞬間螺男,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工纵穿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留下隧,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓谓媒,卻偏偏與公主長得像淆院,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子句惯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理迫筑,服務(wù)發(fā)現(xiàn),斷路器宗弯,智...
    卡卡羅2017閱讀 134,660評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,822評論 6 342
  • 八朝古都,文化名城邓厕。位處中州腹地逝嚎,立夏商舊畿之上,皇天后土详恼,群雄逐鹿場;背臨九曲黃河补君,懷千里平川沃野,華夏搖籃昧互,農(nóng)...
    樸雨閱讀 2,444評論 5 5
  • 大v賺錢嗎挽铁,其實(shí)依照銷售界提成10%已不算少了,可總覺得還是很少敞掘,還是因銷售量沒上去叽掘,可還是我忍不住去推廣,一是因...
    姝墨閱讀 166評論 0 0
  • 突然有點(diǎn)失落玖雁,不是因?yàn)椴荒艹鲞h(yuǎn)門更扁,而是生完孩子了也看完那么多書后,越發(fā)現(xiàn)自己的無能,總想認(rèn)真學(xué)習(xí)考試浓镜,卻因?yàn)橐磺械?..
    文澍閱讀 264評論 0 0