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

SpringBoot中@RestControllerAdvice注解實(shí)現(xiàn)全局異常處理類

 更新時(shí)間:2024年01月17日 08:49:17   作者:吃青椒的秋草鸚鵡  
這篇文章主要介紹了SpringBoot中@RestControllerAdvice注解全局異常處理類,springboot中使用@RestControllerAdvice注解,完成優(yōu)雅的全局異常處理類,可以針對(duì)所有異常類型先進(jìn)行通用處理后再對(duì)特定異常類型進(jìn)行不同的處理操作,需要的朋友可以參考下

需求

springboot中使用@RestControllerAdvice注解,完成優(yōu)雅的全局異常處理類,可以針對(duì)所有異常類型先進(jìn)行通用處理后再對(duì)特定異常類型進(jìn)行不同的處理操作。

注解講解

@RestControllerAdvice注解

@RestControllerAdvice是一個(gè)用于定義全局異常處理器的注解。當(dāng)應(yīng)用程序內(nèi)發(fā)生未捕獲的異常時(shí),全局異常處理器將捕獲該異常并返回對(duì)應(yīng)的響應(yīng),以避免應(yīng)用程序崩潰。它可以處理所有控制器中拋出的異常,包括請(qǐng)求處理方法中的異常、控制器構(gòu)造函數(shù)中的異常等。

@RestControllerAdvice注解是@ControllerAdvice和@ResponseBody注解的組合,它的作用是將所有的異常處理結(jié)果都以JSON格式返回給客戶端。

具體來說,當(dāng)控制器中發(fā)生異常時(shí),SpringBoot會(huì)在全局異常處理器中查找與異常匹配的處理方法,并執(zhí)行該方法來處理異常。

處理方法可以返回任何類型的值,如果返回對(duì)象是DataVO類型,則會(huì)將其轉(zhuǎn)換為JSON格式并返回給客戶端。

如果返回值是String類型,則會(huì)將其解釋為視圖名稱,并使用視圖解析器來解析視圖并生成HTML響應(yīng)。

因此,使用@RestControllerAdvice注解可以方便地定義全局異常處理器,并將所有異常處理結(jié)果以JSON格式返回給客戶端。

@ExceptionHandler注解

@ExceptionHandler是一個(gè)注解,用于定義異常處理方法。

當(dāng)控制器中發(fā)生異常時(shí),Spring Boot會(huì)在@ControllerAdvice或@RestControllerAdvice注解的類中查找與異常匹配的@ExceptionHandler注解標(biāo)記的方法,并執(zhí)行該方法來處理異常。

@ExceptionHandler注解可以定義一個(gè)或多個(gè)異常類型,并將它們映射到對(duì)應(yīng)的異常處理方法。當(dāng)控制器中發(fā)生指定類型的異常時(shí),SpringBoot會(huì)自動(dòng)調(diào)用對(duì)應(yīng)的異常處理方法,并將異常對(duì)象傳遞給該方法作為參數(shù)。

一般的全局異常處理類

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final String DEFAULT_ERROR_MESSAGE = "系統(tǒng)繁忙,請(qǐng)稍后再試";
    @ExceptionHandler(value = {SQLIntegrityConstraintViolationException.class})
    public DataVO handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) {
        log.error(e.getMessage(), e);
        return new DataVO(SysConstant.CODE_ERROR, "當(dāng)前主鍵存在于其他表的外鍵約束,請(qǐng)先處理父表中的該外鍵");
    }
    @ExceptionHandler(value = {FileNotFoundException.class})
    public DataVO handleFileNotFoundException(FileNotFoundException e) {
        log.error(e.getMessage(), e);
        return new DataVO(SysConstant.CODE_ERROR, "路徑不存在");
    }
    @ExceptionHandler(value = {Exception.class})
    public DataVO handleException(Exception e) {
        log.error(e.getMessage(), e);
        return new DataVO(SysConstant.CODE_ERROR, DEFAULT_ERROR_MESSAGE);
    }
}

如例所示,使用@RestControllerAdvice注解聲明了GlobalExceptionHandler作為全局異常處理類,在這個(gè)類中的方法使用@ExceptionHandler注解指定某個(gè)方法處理對(duì)應(yīng)的錯(cuò)誤類型。

在這個(gè)一般的全局處理類中,@ExceptionHandler注解會(huì)根據(jù)異常類型選擇最精確的處理方法進(jìn)行處理,如果沒有找到對(duì)應(yīng)的處理方法,則會(huì)選擇更加通用的處理方法。這樣的處理方式會(huì)導(dǎo)致代碼重復(fù),每個(gè)處理方法都需要寫一遍通用的操作,例如日志記錄。

改進(jìn)全局異常處理類

為了解決這個(gè)問題,我們可以將通用的異常處理邏輯抽象到一個(gè)方法中,并在處理方法中調(diào)用該方法

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final String DEFAULT_ERROR_MESSAGE = "系統(tǒng)繁忙,請(qǐng)稍后再試";
    @ExceptionHandler(value = {SQLIntegrityConstraintViolationException.class})
    public DataVO handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) {
        log.error(e.getMessage(), e);
        return handleException(DEFAULT_ERROR_MESSAGE, e);
    }
    @ExceptionHandler(value = {FileNotFoundException.class})
    public DataVO handleFileNotFoundException(FileNotFoundException e) {
        log.error(e.getMessage(), e);
        return handleException(DEFAULT_ERROR_MESSAGE, e);
    }
    @ExceptionHandler(value = {Exception.class})
    public DataVO handleException(Exception e) {
        log.error(e.getMessage(), e);
        return handleException(DEFAULT_ERROR_MESSAGE, e);
    }
    private DataVO handleException(String defaultMessage, Throwable e) {
        if (e instanceof BusinessException) {
            return new DataVO(SysConstant.CODE_ERROR, e.getMessage());
        } else if (e instanceof MethodArgumentNotValidException) {
            return new DataVO(SysConstant.CODE_ERROR, ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage());
        } else {
            return new DataVO(SysConstant.CODE_ERROR, defaultMessage);
        }
    }
}

在這個(gè)示例中,定義了一個(gè)私有方法handleException,該方法接受一個(gè)默認(rèn)錯(cuò)誤消息和一個(gè)Throwable對(duì)象作為參數(shù),并返回一個(gè)DataVO對(duì)象。

在處理方法中,調(diào)用handleException方法來處理異常,并將默認(rèn)錯(cuò)誤消息作為參數(shù)傳遞給handleException方法。

這樣,我們就可以將通用的異常處理邏輯抽象到一個(gè)方法中,避免了重復(fù)代碼。同時(shí),我們也可以在handleException方法中添加自己的邏輯,例如記錄日志等。

優(yōu)雅的全局異常處理類

handleException方法中的if-else語句太過臃腫,可以使用Map來優(yōu)化這個(gè)方法

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final String errorMsg = SysConstant.DEFAULT_ERROR;
    private static final Map<Class<? extends Throwable>, Function<Throwable, DataVO<Null>>> EXCEPTION_HANDLER_MAP = new HashMap<>();
    static {
        EXCEPTION_HANDLER_MAP.put(RuntimeException.class, e -> new DataVO<>(SysConstant.CODE_ERROR, e.getMessage()));
        EXCEPTION_HANDLER_MAP.put(DataIntegrityViolationException.class, e -> new DataVO<>(SysConstant.CODE_ERROR, "當(dāng)前主鍵存在于其他表的外鍵約束,請(qǐng)先處理父表中的該外鍵"));
        EXCEPTION_HANDLER_MAP.put(FileNotFoundException.class, e -> new DataVO<>(SysConstant.CODE_ERROR, "路徑不存在"));
    }
    @ExceptionHandler(Exception.class)
    public DataVO<Null> handleException(Exception e) {
        log.error(e.toString());
        return EXCEPTION_HANDLER_MAP.getOrDefault(e.getClass(), t -> new DataVO<>(SysConstant.CODE_ERROR, errorMsg)).apply(e);
    }
}

在這個(gè)示例中,使用Map來存儲(chǔ)異常處理函數(shù),每個(gè)函數(shù)都接受一個(gè)Throwable對(duì)象作為參數(shù),并返回一個(gè)DataVO對(duì)象。

在處理方法中,根據(jù)異常類型從Map中獲取對(duì)應(yīng)的處理函數(shù),如果沒有找到對(duì)應(yīng)的處理函數(shù),則使用默認(rèn)的處理函數(shù)。

然后,調(diào)用獲取到的處理函數(shù)來處理異常。這樣,就可以將異常處理函數(shù)集中在一個(gè)Map中,避免了if-else語句的臃腫。同時(shí),也可以在異常處理函數(shù)handleException中添加自己的邏輯,例如記錄日志等。

我的通用值對(duì)象類DataVO(Data Value Object)

@Data
//@JsonPropertyOrder({"code","msg","count","data"})//指定返回給前端的字段順序
public class DataVO<T> {
    private Integer code = 0;
    private String msg = "";
    private Long count;
    private List<T> data;
    public DataVO() {
    }
    public DataVO(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public DataVO(Integer code, String msg, Long count, List<T> data) {
        this.code = code;
        this.msg = msg;
        this.count = count;
        this.data = data;
    }
}

遇到問題

在測(cè)試的時(shí)候要處理外鍵約束報(bào)錯(cuò)問題,控制臺(tái)發(fā)現(xiàn)報(bào)錯(cuò)原因是SQLIntegrityConstraintViolationException,于是我在靜態(tài)異常Map中加入了SQLIntegrityConstraintViolationException處理,但是發(fā)現(xiàn)并沒有正常處理,還是返回的默認(rèn)異常信息。

于是在控制臺(tái)輸出了一下那個(gè)錯(cuò)誤的類,e.getClass()發(fā)現(xiàn)實(shí)際上是DataIntegrityViolationException,SQLIntegrityConstraintViolationException只是cause,改完之后測(cè)試成功處理異常并返回特定異常信息給前端。

到此這篇關(guān)于SpringBoot中@RestControllerAdvice注解全局異常處理類的文章就介紹到這了,更多相關(guān)@RestControllerAdvice注解全局異常內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring-data-redis 2.0 的使用示例代碼

    spring-data-redis 2.0 的使用示例代碼

    這篇文章主要介紹了spring-data-redis 2.0 的使用示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Java 實(shí)現(xiàn)文件批量重命名親測(cè)可用(精簡(jiǎn)版)

    Java 實(shí)現(xiàn)文件批量重命名親測(cè)可用(精簡(jiǎn)版)

    本文給大家分享一段自己寫的java代碼實(shí)現(xiàn)文件批量重命名,親測(cè)試過沒有任何問題,大家可以放心使用
    2016-11-11
  • Java 實(shí)用工具類Spring 的 StopWatch常用方法

    Java 實(shí)用工具類Spring 的 StopWatch常用方法

    StopWatch 是 Spring 框架中極其實(shí)用的開發(fā)輔助工具,它為性能分析和調(diào)試提供了輕量但強(qiáng)大的能力,使用簡(jiǎn)單、無需復(fù)雜配置,本文給大家介紹Java 實(shí)用工具類Spring 的 StopWatch常用方法,感興趣的朋友一起看看吧
    2025-04-04
  • java 接口回調(diào)實(shí)例詳解

    java 接口回調(diào)實(shí)例詳解

    這篇文章主要介紹了java 接口回調(diào)實(shí)例詳解的相關(guān)資料,所謂回調(diào)就是使用java中的多態(tài),需要的朋友可以參考下
    2017-07-07
  • springboot基于Mybatis mysql實(shí)現(xiàn)讀寫分離

    springboot基于Mybatis mysql實(shí)現(xiàn)讀寫分離

    這篇文章主要介紹了springboot基于Mybatis mysql實(shí)現(xiàn)讀寫分離,需要的朋友可以參考下
    2019-06-06
  • Java異常報(bào)錯(cuò):java.nio.file.FileSystemException的多種解決方案

    Java異常報(bào)錯(cuò):java.nio.file.FileSystemException的多種解決方案

    在Java應(yīng)用程序中處理文件和目錄時(shí),java.nio.file.FileSystemException是一個(gè)常見的異常,這個(gè)異常發(fā)生在嘗試進(jìn)行文件系統(tǒng)操作時(shí),本文將詳細(xì)探討FileSystemException的成因,并提供多種解決方案,需要的朋友可以參考下
    2024-12-12
  • Spring如何實(shí)現(xiàn)輸出帶動(dòng)態(tài)標(biāo)簽的日志

    Spring如何實(shí)現(xiàn)輸出帶動(dòng)態(tài)標(biāo)簽的日志

    文章介紹了如何通過動(dòng)態(tài)標(biāo)簽日志實(shí)現(xiàn),解決了部分業(yè)務(wù)代碼在多個(gè)模塊中調(diào)用時(shí)日志無法直觀看出來源的問題,主要通過ThreadLocal存儲(chǔ)業(yè)務(wù)標(biāo)簽,并在日志輸出時(shí)插入該標(biāo)簽,實(shí)現(xiàn)日志的動(dòng)態(tài)標(biāo)簽功能,感興趣的朋友一起看看吧
    2024-12-12
  • struts2靜態(tài)資源映射代碼示例

    struts2靜態(tài)資源映射代碼示例

    這篇文章主要介紹了struts2靜態(tài)資源映射的相關(guān)內(nèi)容,涉及了具體代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • 深度deepin安裝以及jdk、tomcat、Nginx安裝教程

    深度deepin安裝以及jdk、tomcat、Nginx安裝教程

    這篇文章主要給大家介紹了關(guān)于深度deepin安裝以及jdk、tomcat、Nginx安裝的相關(guān)資料,按照文中介紹的方法可以輕松的實(shí)現(xiàn)安裝,對(duì)大家的工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-01-01
  • RocketMQ設(shè)計(jì)之主從復(fù)制和讀寫分離

    RocketMQ設(shè)計(jì)之主從復(fù)制和讀寫分離

    這篇文章主要介紹了RocketMQ設(shè)計(jì)之主從復(fù)制和讀寫分離,RocketMQ提高消費(fèi)避免Broker發(fā)生單點(diǎn)故障引起B(yǎng)roker上的消息無法及時(shí)消費(fèi),下文關(guān)于了RocketMQ的相關(guān)內(nèi)容,需要的小伙伴可以參考一下
    2022-03-03

最新評(píng)論

高安市| 双鸭山市| 景泰县| 达孜县| 丽江市| 登封市| 施甸县| 景宁| 宜兴市| 板桥市| 五大连池市| 工布江达县| 马龙县| 汝城县| 濮阳县| 苍山县| 米泉市| 靖州| 镇安县| 水富县| 长垣县| 阳高县| 尖扎县| 漳平市| 大同市| 五华县| 克山县| 东辽县| 高陵县| 浦江县| 霍林郭勒市| 嘉峪关市| 英吉沙县| 罗江县| 河津市| 昭平县| 精河县| 梅河口市| 波密县| 南丹县| 墨玉县|