1. 程式人生 > >@ControllerAdvice自定義異常統一處理

@ControllerAdvice自定義異常統一處理

正常來說一個系統肯定有很多業務異常。而這些業務異常的資訊如何返回給前臺呈現給使用者。比如使用者的某些操作不被允許,需要給使用者提示。

Spring 提供了@ControllerAdvice這個註解,這個註解可以實現全域性異常處理,全域性資料繫結,全域性資料預處理,這裡主要說下使用這個註解實現全域性異常處理。

1.定義我們自己的業務異常ErrorCodeException

package com.nijunyang.exception.exception;

/**
 * Description: 
 * Created by nijunyang on 2019/12/20 9:36
 */
public class ErrorCodeException extends RuntimeException {

    private int code;
    /**
     * 用於填充資原始檔中佔位符
     */
    private Object[] args;

    public ErrorCodeException(int code, Object... args) {
        this.code = code;
        this.args = args;
    }

    public int getCode() {
        return code;
    }

    public Object[] getArgs() {
        return args;
    }

}

 

2.編寫統一異常處理器RestExceptionHandler,使用@ControllerAdvice註解修飾,在異常處理器編寫針對某個異常的處理方法,使用@ExceptionHandler註解指向某個指定異常。當代碼中拋了該異常就會進入此方法執行,從而返回我們處理後的資訊給請求者。

3.資原始檔放置提示資訊,根據錯誤碼去匹配提示資訊。

 

package com.nijunyang.exception.handler;

import com.nijunyang.exception.exception.ErrorCodeException;
import com.nijunyang.exception.model.RestErrorResponse;
import com.nijunyang.exception.model.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Locale;

/**
 * Description: 控制層統一異常處理
 * Created by nijunyang on 2019/12/20 9:33
 */
@ControllerAdvice
public class RestExceptionHandler {

    @Autowired
    private MessageSource messageSource;

    //locale可以處理國際化資原始檔,不同的語言
    @ExceptionHandler(value = ErrorCodeException.class)
    public final ResponseEntity<RestErrorResponse> handleBadRequestException(ErrorCodeException errorCodeException, Locale locale) {
        String message = messageSource.getMessage(String.valueOf(errorCodeException.getCode()), errorCodeException.getArgs(), locale);
        RestErrorResponse restErrorResponse = new RestErrorResponse(Status.FAILED, errorCodeException.getCode(), message);
        return new ResponseEntity<>(restErrorResponse, HttpStatus.OK);
    }
}

 

 

 

4.配置檔案指向資原始檔位置(spring.messages.basename=xxx)

 

 

 

 

 

 spring.messages.basename指向資源的字首名字就行了,後面的國家語言標誌不需要,Locale會根據系統的語言去識別,資原始檔需要配置一個預設的(messages.properties),不然啟動的時候可能無法正常注入資源,因為預設的是去載入不帶國家語言標誌的檔案。

當然字首隨便配置什麼都可以 只要再springboot的配置檔案spring.messages.basename的路徑配置正確就行,就像這樣子也是可以的

 

 

 

5.控制層模擬異常丟擲:

package com.nijunyang.exception.controller;

import com.nijunyang.exception.exception.ErrorCodeException;
import com.nijunyang.exception.model.ErrorCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description: 
 * Created by nijunyang on 2019/12/20 9:58
 */
@RestController
@RequestMapping("/error")
public class Controller {

    @GetMapping("/file")
    public ResponseEntity test() {
        //模擬檔案不存在
        String path = "a/b/c/d.txt";
        throw new ErrorCodeException(ErrorCode.FILE_DOES_NOT_EXIST_51001, path);
    }
}

6.前臺呼叫結果

 

z/b/c/d.txt就去填充了資原始檔中的佔位符

 

錯誤碼:

package com.nijunyang.exception.model;

/**
 * Description:
 * Created by nijunyang on 2020/1/20 20:28
 */
public final class ErrorCode {
    public static int FILE_DOES_NOT_EXIST_51001 = 51001;
}

結果狀態:

package com.nijunyang.exception.model;

/**
 * Description: 
 * Created by nijunyang on 2019/12/20 10:21
 */
public enum Status {
    SUCCESS,
    FAILED
}

異常統一結果返回物件

package com.nijunyang.exception.model;

/**
 * Description: 
 * Created by nijunyang on 2019/12/20 9:38
 */
public class RestErrorResponse {

    private Status status;
    /**
     * 錯誤碼
     */
    private Integer errorCode;
    /**
     * 錯誤資訊
     */
    private String errorMsg;

    public RestErrorResponse(Status status, Integer errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
        this.status = status;
    }

    public Integer getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(Integer errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public Status getStatus() {
        return status;
    }

}

pom檔案依賴:springBoot版本是2.1.7.RELEASE

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
    </dependencies>

完整程式碼:https://github.com/bluedarkni/study.git  ---->springboot--->exception項