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

SpringBoot項目實現(xiàn)統(tǒng)一異常處理的最佳方案

 更新時間:2024年02月05日 09:26:06   作者:程序員偏安  
在前后端分離的項目開發(fā)過程中,我們通常會對數(shù)據(jù)返回格式進行統(tǒng)一的處理,這樣可以方便前端人員取數(shù)據(jù),后端發(fā)生異常時同樣會使用此格式將異常信息返回給前端,本文介紹了如何在SpringBoot項目中實現(xiàn)統(tǒng)一異常處理,如有錯誤,還望批評指正

前言

近日心血來潮想做一個開源項目,目標是做一款可以適配多端、功能完備的模板工程,包含后臺管理系統(tǒng)和前臺系統(tǒng),開發(fā)者基于此項目進行裁剪和擴展來完成自己的功能開發(fā)。本項目為前后端分離開發(fā),后端基于Java21SpringBoot3開發(fā),后端使用Spring Security、JWTSpring Data JPA等技術(shù)棧,前端提供了vueangular、reactuniapp、微信小程序等多種腳手架工程。

項目地址:https://gitee.com/breezefaith/fast-alden

在前后端分離的項目開發(fā)過程中,我們通常會對數(shù)據(jù)返回格式進行統(tǒng)一的處理,這樣可以方便前端人員取數(shù)據(jù),后端發(fā)生異常時同樣會使用此格式將異常信息返回給前端。本文將介紹在SpringBoot項目中如何實現(xiàn)統(tǒng)一異常處理。

實現(xiàn)步驟

定義統(tǒng)一響應對象類

/**
 * 響應結(jié)果類
 *
 * @param <T> 任意類型
 */
@Data
public class ResponseResult<T> {
    /**
     * 響應狀態(tài)碼,200是正常,非200表示異常
     */
    private int status;
    /**
     * 異常編號
     */
    private String errorCode;
    /**
     * 異常信息
     */
    private String message;
    /**
     * 響應數(shù)據(jù)
     */
    private T data;
    public static <T> ResponseResult<T> success() {
        return success(HttpServletResponse.SC_OK, null, null);
    }
    public static <T> ResponseResult<T> success(T data) {
        return success(HttpServletResponse.SC_OK, null, data);
    }
    public static <T> ResponseResult<T> fail(String message) {
        return fail(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, message, null);
    }
    public static <T> ResponseResult<T> fail(String errorCode, String message) {
        return fail(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorCode, message, null);
    }
    public static <T> ResponseResult<T> success(int status, String message, T data) {
        ResponseResult<T> r = new ResponseResult<>();
        r.setStatus(status);
        r.setMessage(message);
        r.setData(data);
        return r;
    }
    public static <T> ResponseResult<T> fail(int status, String errorCode, String message) {
        return fail(status, errorCode, message, null);
    }
    public static <T> ResponseResult<T> fail(int status, String errorCode, String message, T data) {
        ResponseResult<T> r = new ResponseResult<>();
        r.setStatus(status);
        r.setErrorCode(errorCode);
        r.setMessage(message);
        r.setData(data);
        return r;
    }
}

定義業(yè)務異常枚舉接口和實現(xiàn)

通常一個系統(tǒng)中的自定義業(yè)務異常是可窮舉的,可以考慮通過定義枚舉的方式來列舉所有的業(yè)務異常。

首先我們來定義一個異常信息枚舉的基類接口。

public interface IBizExceptionEnum {
    String getCode();
    String getMessage();
}

再給出一個常用的異常信息的枚舉類,如果有其他業(yè)務模塊的異常信息,同樣可以通過實現(xiàn)IBizExceptionEnum接口來進行定義。

@Getter
public enum BizExceptionEnum implements IBizExceptionEnum {
    ENTITY_IS_NULL("Base_Entity_Exception_0001", "實體為空"),
    ENTITY_ID_IS_NULL("Base_Entity_Exception_0002", "實體id字段為空"),
    ENTITY_ID_IS_DUPLCATED("Base_Entity_Exception_0003", "實體id字段%s重復");
    private final String code;
    private final String message;
    BizExceptionEnum(String code, String message) {
        this.code = code;
        this.message = message;
    }
}

定義業(yè)務異常基類

業(yè)務異?;?code>BizException繼承自RuntimeException,代碼中主動拋出的異常建議都包裝為該類的實例。

/**
 * 業(yè)務異?;?,支持參數(shù)化的異常信息
 */
@Getter
@Setter
public class BizException extends RuntimeException {
    private String code;
    private Object[] args;
    public BizException() {
        super();
    }
    public BizException(String message) {
        super(message);
    }
    public BizException(Throwable cause) {
        super(cause);
    }
    public BizException(String message, Throwable cause) {
        super(message, cause);
    }
    public BizException(Throwable cause, String code, String message, Object... args) {
        super(message, cause);
        this.code = code;
        this.args = args;
    }
    public BizException(String code, String message, Object... args) {
        super(message);
        this.code = code;
        this.args = args;
    }
    public BizException(IBizExceptionEnum exceptionEnum, Object... args) {
        this(exceptionEnum.getCode(), exceptionEnum.getMessage(), args);
    }
    public BizException(Throwable cause, IBizExceptionEnum exceptionEnum, Object... args) {
        this(cause, exceptionEnum.getCode(), exceptionEnum.getMessage(), args);
    }
    @Override
    public String getMessage() {
        if (code != null) {
            if (args != null && args.length > 0) {
                return String.format(super.getMessage(), args);
            }
        }
        return super.getMessage();
    }
}

定義全局異常處理切面

本步驟需要使用@RestControllerAdvice注解,它是一個組合注解,由@ControllerAdvice、@ResponseBody組成,而@ControllerAdvice繼承了@Component,因此@RestControllerAdvice本質(zhì)上是個Component,用于定義@ExceptionHandler,@InitBinder@ModelAttribute方法,適用于所有使用@RequestMapping方法。

還要用到@ExceptionHandler注解,可以認為它是一個異常攔截器,它采用“就近原則”,存在多個滿足條件的異常處理器時會選擇最接近的一個來使用。它本質(zhì)上就是使用Spring AOP定義的一個切面,在系統(tǒng)拋出異常后執(zhí)行。

具體實現(xiàn)代碼如下:

/**
 * 全局異常處理切面
 */
@RestControllerAdvice
public class GlobalExceptionHandlerAdvice {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandlerAdvice.class);
    @ExceptionHandler({BizException.class})
    public ResponseResult<Object> handleBizException(BizException e, HttpServletRequest request, HttpServletResponse response) {
        log.error(e.getCode() + ": " + e.getMessage(), e);
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return ResponseResult.fail(e.getCode(), e.getMessage());
    }
    @ExceptionHandler({RuntimeException.class, Exception.class})
    public ResponseResult<Object> handleRuntimeException(Exception e, HttpServletRequest request, HttpServletResponse response) {
        log.error(e.getMessage(), e);
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return ResponseResult.fail(e.getMessage());
    }
}

上述代碼會對系統(tǒng)中拋出的BizException、RuntimeExceptionException對象進行處理,把異常包裝為ResponseResult對象后將異常編號和異常信息返回給前端。

測試和驗證

下面我們就可以定義一個Controller類來進行簡單的測試。

@RestController
@RequestMapping("/demo")
public class DemoController {
    @GetMapping("/method1")
    public ResponseResult<Integer> method1() {
        throw new BizException(BizExceptionEnum.ENTITY_IS_NULL);
    }
    @GetMapping("/method2")
    public void method2() {
        throw new BizException(BizExceptionEnum.ENTITY_ID_IS_NULL);
    }
    @GetMapping(value = "/method3")
    public String method3() {
        throw new BizException(BizExceptionEnum.ENTITY_ID_IS_DUPLCATED, "1");
    }
    @GetMapping(value = "/method4")
    public String method4() {
        // 拋出ArithmeticException異常
        return String.valueOf(1 / 0);
    }
}

總結(jié)

本文介紹了如何在SpringBoot項目中實現(xiàn)統(tǒng)一異常處理,如有錯誤,還望批評指正。

在后續(xù)實踐中我也是及時更新自己的學習心得和經(jīng)驗總結(jié),希望與諸位看官一起進步。

到此這篇關(guān)于SpringBoot項目實現(xiàn)統(tǒng)一異常處理的最佳方案的文章就介紹到這了,更多相關(guān)SpringBoot統(tǒng)一異常處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot 用監(jiān)聽器統(tǒng)計在線人數(shù)案例分析

    springboot 用監(jiān)聽器統(tǒng)計在線人數(shù)案例分析

    這篇文章主要介紹了springboot 用監(jiān)聽器統(tǒng)計在線人數(shù)案例分析,質(zhì)是統(tǒng)計session 的數(shù)量,思路很簡單,具體實例代碼大家參考下本文
    2018-02-02
  • 詳解SpringBoot中的統(tǒng)一結(jié)果返回與統(tǒng)一異常處理

    詳解SpringBoot中的統(tǒng)一結(jié)果返回與統(tǒng)一異常處理

    這篇文章主要將通過詳細的討論和實例演示來幫助你更好地理解和應用Spring Boot中的統(tǒng)一結(jié)果返回和統(tǒng)一異常處理,感興趣的小伙伴可以了解下
    2024-03-03
  • Java哈希表HashTable(又稱散列表)的實現(xiàn)及練習題

    Java哈希表HashTable(又稱散列表)的實現(xiàn)及練習題

    哈希表又稱為散列表,是一種通過哈希函數(shù)將數(shù)據(jù)映射到特定位置的數(shù)據(jù)結(jié)構(gòu),這篇文章主要介紹了Java哈希表HashTable(又稱散列表)的實現(xiàn)及練習題的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-12-12
  • Java工具類之@RequestMapping注解

    Java工具類之@RequestMapping注解

    今天帶大家來學習Java工具類,文中對注解@RequestMapping作了非常詳細的介紹,對正在學習java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • Java多線程中的互斥鎖解析

    Java多線程中的互斥鎖解析

    這篇文章主要介紹了Java多線程中的互斥鎖解析,Java語言中,引入了對象互斥鎖的概念,來保證共享數(shù)據(jù)操作的完整性,每個對象都對應于一個可稱為互斥鎖的標記,這個標記用來保證在任一時刻,只能有一個線程訪問該對象,需要的朋友可以參考下
    2023-09-09
  • Java8 forEach常用場景代碼實例

    Java8 forEach常用場景代碼實例

    這篇文章主要介紹了Java8 forEach常用場景代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot項目多模塊項目中父類與子類pom.xml的關(guān)聯(lián)問題小結(jié)

    SpringBoot項目多模塊項目中父類與子類pom.xml的關(guān)聯(lián)問題小結(jié)

    這篇文章主要介紹了SpringBoot項目多模塊項目中父類與子類pom.xml的關(guān)聯(lián)問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-04-04
  • Java多線程間的5種通信方式小結(jié)

    Java多線程間的5種通信方式小結(jié)

    有兩個線程,A 線程向一個集合里面依次添加元素“abc”字符串,一共添加十次,當添加到第五次的時候,希望 B 線程能夠收到 A 線程的通知,然后 B 線程執(zhí)行相關(guān)的業(yè)務操作,本文介紹的5種通信方式都是基本這兩種模型來實現(xiàn)的,需要的朋友可以參考下
    2023-10-10
  • Java實現(xiàn)猜字小游戲

    Java實現(xiàn)猜字小游戲

    這篇文章給大家分享小編隨手寫的猜字小游戲,基于java代碼寫的,感興趣的朋友跟隨小編一起看看吧
    2019-11-11
  • java 讀取文件方法的總結(jié)

    java 讀取文件方法的總結(jié)

    這篇文章主要介紹了java 讀取文件方法的總結(jié)的相關(guān)資料,這里提供文件讀取5種方法并附實例,需要的朋友可以參考下
    2017-08-08

最新評論

逊克县| 和平区| 开化县| 五常市| 凤翔县| 若羌县| 延津县| 英山县| 武宣县| 临沧市| 景洪市| 来凤县| 林芝县| 湛江市| 温宿县| 仁怀市| 许昌县| 休宁县| 永济市| 绥德县| 洛阳市| 辽宁省| 江孜县| 石屏县| 慈溪市| 玉门市| 双流县| 晋城| 泸定县| 洞头县| 宜川县| 霍林郭勒市| 大渡口区| 晋城| 雅安市| 承德市| 梨树县| 淅川县| 麻栗坡县| 武邑县| 瓦房店市|