欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

需求

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

注解講解

@RestControllerAdvice注解

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

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

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

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

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

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

@ExceptionHandler注解

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

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

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

一般的全局異常處理類

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final String DEFAULT_ERROR_MESSAGE = "系統(tǒng)繁忙,請稍后再試";
    @ExceptionHandler(value = {SQLIntegrityConstraintViolationException.class})
    public DataVO handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) {
        log.error(e.getMessage(), e);
        return new DataVO(SysConstant.CODE_ERROR, "當前主鍵存在于其他表的外鍵約束,請先處理父表中的該外鍵");
    }
    @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作為全局異常處理類,在這個類中的方法使用@ExceptionHandler注解指定某個方法處理對應的錯誤類型。

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

改進全局異常處理類

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

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final String DEFAULT_ERROR_MESSAGE = "系統(tǒ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);
        }
    }
}

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

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

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

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

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

@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, "當前主鍵存在于其他表的外鍵約束,請先處理父表中的該外鍵"));
        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);
    }
}

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

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

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

我的通用值對象類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;
    }
}

遇到問題

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

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

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

相關文章

  • request如何獲取完整url(包括域名、端口、參數(shù))

    request如何獲取完整url(包括域名、端口、參數(shù))

    這篇文章主要介紹了request如何獲取完整url(包括域名、端口、參數(shù))問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • JVM中的flag設置詳解

    JVM中的flag設置詳解

    這篇文章主要介紹了JVM中的flag設置詳解,涉及堆大小設置,收集器設置等香公館內(nèi)容,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • Spring?Security認證器實現(xiàn)過程詳解

    Spring?Security認證器實現(xiàn)過程詳解

    一些權限框架一般都包含認證器和決策器,前者處理登陸驗證,后者處理訪問資源的控制,這篇文章主要介紹了Spring?Security認證器實現(xiàn)過程,需要的朋友可以參考下
    2022-06-06
  • 詳解java封裝繼承多態(tài)

    詳解java封裝繼承多態(tài)

    這篇文章主要介紹了java封裝繼承多態(tài),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • Jsoup獲取全國地區(qū)數(shù)據(jù)屬性值(省市縣鎮(zhèn)村)

    Jsoup獲取全國地區(qū)數(shù)據(jù)屬性值(省市縣鎮(zhèn)村)

    這篇文章主要介紹了Jsoup獲取全國地區(qū)數(shù)據(jù)屬性值(省市縣鎮(zhèn)村)的相關資料,需要的朋友可以參考下
    2015-10-10
  • Spring Boot 在啟動時進行配置文件加解密的方法詳解

    Spring Boot 在啟動時進行配置文件加解密的方法詳解

    這篇文章主要介紹了Spring Boot 在啟動時進行配置文件加解密的方法,本文通過實例給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Java中的CyclicBarrier同步屏障詳解

    Java中的CyclicBarrier同步屏障詳解

    這篇文章主要介紹了Java中的CyclicBarrier同步屏障詳解,CyclicBarrier也叫同步屏障,在JDK1.5被引入,可以讓一組線程達到一個屏障時被阻塞,直到最后一個線程達到屏障時,屏障才會開門,所有被阻塞的線程才會繼續(xù)執(zhí)行,需要的朋友可以參考下
    2023-09-09
  • Java之多個線程順序循環(huán)執(zhí)行的幾種實現(xiàn)

    Java之多個線程順序循環(huán)執(zhí)行的幾種實現(xiàn)

    這篇文章主要介紹了Java之多個線程順序循環(huán)執(zhí)行的幾種實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 查看Spring容器中bean的五種方法小結

    查看Spring容器中bean的五種方法小結

    近期在寫Spring項目的時候,需要通過注解的形式去替代之前直接將Bean存放在Spring容器這種方式,以此來簡化對于Bean對象的操作,這篇文章主要給大家介紹了關于如何查看Spring容器中bean的五種方法,需要的朋友可以參考下
    2024-05-05
  • Java JTable 實現(xiàn)日歷的示例

    Java JTable 實現(xiàn)日歷的示例

    這篇文章主要介紹了Java JTable 實現(xiàn)日歷的示例,幫助大家更好的理解和學習Java jtable的使用方法,感興趣的朋友可以了解下
    2020-10-10

最新評論