@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項目


免責聲明!

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



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