SpringBoot:如何優(yōu)雅地處理全局異常?

之前用springboot的時候,只知道捕獲異常使用try{}catch,一個接口一個try{}catch,這也是大多數(shù)開發(fā)人員異常處理的常用方式,雖然屢試不爽,但會造成一個問題,就是一個Controller下面,滿屏幕的try{}catch,看著一點都不優(yōu)雅,一點都不符合小明的氣質,憋了這么久,小明今天終于決定對所有異常實施統(tǒng)一處理的方案。

開發(fā)準備

JDK8、正常的springboot項目

代碼編寫

通用異常處理

其實Spring系列的項目全局異常處理方式早已存在,只不過我們一直忙于搬磚,很少停下腳步去審視這個日夜與我們相伴的朋友。為了貼合主題,本次主要針對SpringBoot全局異常處理進行舉例說明。

SpringBoot中有一個@ControllerAdvice的注解,使用該注解即表示開啟全局異常捕獲,接下來我們只需在自定義的方法上使用@ExceptionHandler注解,并定義捕獲異常的類型,對這種類型的異常進行統(tǒng)一的處理。

舉個例子:

假如我們需要針對NullException(空指針異常,是Java程序員最痛恨的異常,沒有之一)進行全局處理(如下所示)。

@RestControllerAdvice
public class GlobalExceptionHandler {
        /**
     * 處理空指針的異常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =NullPointerException.class)
    public BaseResponseFacade exceptionHandler(HttpServletRequest req, NullPointerException e){
        log.error("發(fā)生空指針異常!原因是:",e);
        return ResponseUtil.error(ResponseCode.ERROR);
    }
}

訥,就這么簡單。其他可能發(fā)生的異常,都可以以這種方式處理快速處理。此處大家應該表現(xiàn)的十分興奮,但請不要高興太早,因為接下來,有更令激動人心的事情。

自定義異常處理

自定義一個異常
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @Description 自定義異常
 * @Date 2019-08-05 15:49
 * @Created by 程序員小明
 */
@Data
@AllArgsConstructor
@Accessors(chain = true)
public class BizException extends RuntimeException {
    /**
     * 錯誤碼
     */
    protected Integer errorCode;
    /**
     * 錯誤信息
     */
    protected String errorMsg;
}

顯而易見,這個異常繼承了RuntimeException,屬于運行時異常。細心的朋友已經(jīng)發(fā)現(xiàn),我使用了Lombok插件,非常契合今天的主題,給大家簡單介紹一下:

lombok是一個可以幫助我們簡化java代碼編寫的工具類,尤其是簡化javabean的編寫,即通過采用注解的方式,消除代碼中的構造方法,getter/setter等代碼,使我們寫的類更加簡潔(如果使用的IDE是idea,需要安裝插件哈)。

定義過之后,我們就可以和之前處理NullException方式一樣處理我們自定義的異常。包括處理其他異常,都是這種方式。直接貼代碼。

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 處理自定義的業(yè)務異常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    public BaseResponseFacade bizExceptionHandler(HttpServletRequest req, BizException e){
        log.error("發(fā)生業(yè)務異常!原因是:{}",e.getErrorMsg());
        return ResponseUtil.error(e.getErrorCode(),e.getErrorMsg());
    }

    /**
     * 處理空指針的異常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =NullPointerException.class)
    public BaseResponseFacade exceptionHandler(HttpServletRequest req, NullPointerException e){
        log.error("發(fā)生空指針異常!原因是:",e);
        return ResponseUtil.error(ResponseCode.ERROR);
    }


    /**
     * 處理其他異常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =Exception.class)
    public BaseResponseFacade exceptionHandler(HttpServletRequest req, Exception e){
        log.error("未知異常!原因是:",e);
        return ResponseUtil.error(ResponseCode.INTERNAL_SERVER_ERROR);
    }
}

整個全局異常處理方式核心就是以上介紹這些。下面用一個Demo給大家舉個例子

@GetMapping("/test")
public BaseResponseFacade test(){
  if(true){
    throw new BizException(1,"error");
  }
  return ResponseUtil.success();
}

地址欄請求,進入這個方法后,會拋出異常,此時全局異常生效,就會返回異常處理過后的信息

{"errorCode":1,"errorMsg":"error","data":null}

到此整個流程都然跑通了。當然,好多地方都可以根據(jù)我們自身實際業(yè)務情況以此為基礎進一步豐富,比如返回數(shù)據(jù)可以改成跳轉某一個具體的頁面。這樣的出場方式是不是都很優(yōu)雅?大家有什么問題,期待各位留言。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 我們開發(fā)過程中,不管是通用代碼的開發(fā)還是業(yè)務代碼的編寫,都涉及到異常的處理,如果不對異常進行封裝處理的話,會導致我...
    AmosZhu閱讀 1,603評論 1 13
  • 八、深入理解java異常處理機制 引子try…catch…finally恐怕是大家再熟悉不過的語句了, 你的答案是...
    壹點零閱讀 1,731評論 0 0
  • JAVA異常與異常處理詳解 一、異常簡介 什么是異常? 異常就是有異于常態(tài),和正常情況不一樣,有錯誤出錯。在jav...
    java大濕兄閱讀 1,039評論 0 11
  • 姓名:李丹丹 公司:山東萬潔環(huán)??萍加邢薰?組別:第373期 利他一組 【日精進打卡第182天】 【知~學習】 ...
    小雨淅淅373閱讀 122評論 0 0
  • 前言 線程池是Java中的一個重要概念,從Android上來說,當我們跟服務端進行數(shù)據(jù)交互的時候我們都知道主線程不...
    老實任閱讀 1,355評論 1 9

友情鏈接更多精彩內容