SpringBoot項目如何做到統一異常處理


在項目中,難免會出現各種各樣的異常,我們希望異常信息盡可能詳細,包括響應狀態碼,響應的字符串異常信息,甚至操作時間等等,這樣可以方便地快速定位到發生異常的位置.所以,一個項目中對於異常的處理就顯得尤為重要.那么,小編就以SpringBoot框架,通過代碼實例展示統一異常的處理方式.

1.首先我們簡單搭建一個SpringBoot框架的項目,項目名稱是exceptionhandler(異常處理)

2.導入相關依賴

導入lombok依賴,提供@getter注解

導入日期工具類JodaTime,提供DateTime.now()方法

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--日期工具類:JodaTime-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

3.編寫application.yml配置文件

注意這里添加了訪問路徑前綴

server:
  port: 8082
  servlet:
    context-path: /exception

4.編寫SpringBoot的啟動類

package com.exception;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ExceptionApplication {
    public static void main(String[] args) {
        SpringApplication.run(ExceptionApplication.class, args);
    }
}

5.編寫異常枚舉類

異常枚舉類中,應該列舉出項目可能出現的所有異常類型,這里只拿數學計算異常舉例

package com.exception.enums;

import lombok.Getter;

/**
 * 異常枚舉類
 */
@Getter
public enum ExceptionEnum {
    ARTITHMETIC(500, "數學計算異常");
    private Integer status;
    private String message;

    ExceptionEnum(Integer status, String message) {
        this.status = status;
        this.message = message;
    }
}

6.編寫自定義異常類

自定義異常類繼承RuntimeException,同時RuntimeException繼承Exception類,而Exception又繼承Throwable類,super方法最終也是Throwable中的方法

package com.exception.exceptions;

import com.exception.enums.ExceptionEnum;
import lombok.Getter;

/**
 * 自定義異常類
 */
@Getter
public class SelfDefinedException extends RuntimeException {
    private Integer status;

    public SelfDefinedException(ExceptionEnum exceptionEnum) {
        super(exceptionEnum.getMessage());
        this.status = exceptionEnum.getStatus();
    }

    public SelfDefinedException(ExceptionEnum exceptionEnum, Throwable cause) {
        super(exceptionEnum.getMessage(), cause);
        this.status = exceptionEnum.getStatus();
    }
}

7.編寫統一異常返回結果類

package com.exception.entity;

import com.exception.exceptions.SelfDefinedException;
import lombok.Getter;
import org.joda.time.DateTime;

/**
 * 統一異常返回結果類
 */
@Getter
public class ExceptionResult {
    private Integer status;
    private String message;
    private String timestamp;

    public ExceptionResult(SelfDefinedException e) {
        this.status = e.getStatus();
        this.message = e.getMessage();
        this.timestamp = DateTime.now().toString("yyyy-MM-dd HH:mm:ss");
    }
}

8.編寫統一異常攔截類

需注意兩個spring注解的作用:

@ControllerAdvice:此注解默認情況下,會攔截所有加了@Controller注解的類

@ExceptionHandler():此注解用在方法上,括號內聲明要處理的異常類型,可以指定多個,這里我們指定的是自定義異常

package com.exception.advice;

import com.exception.entity.ExceptionResult;
import com.exception.exceptions.SelfDefinedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * 統一異常攔截類
 */
@ControllerAdvice
@Slf4j
public class BasicExceptionAdvice {
    @ExceptionHandler(SelfDefinedException.class)
    public ResponseEntity<ExceptionResult> handlerException(SelfDefinedException e) {//參數類型與要處理的異常類型必須匹配
        return ResponseEntity.status(e.getStatus()).body(new ExceptionResult(e));//body中的對象必須和ResponseEntity中的對象一致
    }
}

9.編寫測試類

package com.exception.controller;

import com.exception.enums.ExceptionEnum;
import com.exception.exceptions.SelfDefinedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class TestController {
    @GetMapping("/test")
    public ResponseEntity<String> login() {
        try {
            Integer tempValue = 10 / 0;
        } catch (Exception e) {
            throw new SelfDefinedException(ExceptionEnum.ARTITHMETIC);//catch捕獲異常后,這里throw拋出異常並未處理,所以后面的代碼不會執行
        }
        return ResponseEntity.ok("沒發現異常,返回正確的字符串");
    }
}

10.測試結果

通過IDEA自帶的HTTP Client進行測試,觀察響應結果如下.這樣我們就得到了

總結:

因為項目中會出現各種各樣的異常,所以我們通過一個異常枚舉類將所有的異常進行列舉.我們希望捕獲自己定義的異常,所以編寫了一個自定義異常類,同時我們希望響應的異常結果規則且詳細,所以通過一個統一異常結果類來實現.最重要的是,我們還需要一個異常攔截類,這樣在我們拋出自定義異常的時候,這個異常攔截類能夠進行攔截,並將我們定義好的響應結果(也就是異常體所有信息)返回.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM