1. 程式人生 > 其它 >自定義註解實現引數校驗

自定義註解實現引數校驗

技術標籤:工具方法

自定義註解實現引數校驗

一.定義註解類

/**
 * 使用者驗證狀態是否在指定範圍內的註解
 */
@Documented
// JVM會讀取註解,同時會儲存到class檔案中
@Retention(RetentionPolicy.RUNTIME)
// 用於欄位或者方法引數
@Target({ElementType.FIELD,ElementType.PARAMETER})
// 指定檢驗處理類
@Constraint(validatedBy = FlagValidatorClass.class)
public @interface FlagValidator {

	// 校驗引數是否在某個int 陣列中
int[] value() default {}; // 出現檢驗失敗的錯誤訊息 String message() default "flag is not found"; // 分組 Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }

二.定義校驗類

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/** * 狀態標記校驗器 校驗 FlagValidator 註解的地方 * * ConstraintValidator<FlagValidator, Integer> * FlagValidator : 校驗的註解 * Integer : 前端傳的值 */ public class FlagValidatorClass implements ConstraintValidator<FlagValidator, Integer> { private int[] values; // 初始化方法 @Override
public void initialize(FlagValidator flagValidator) { // 獲取到 設定了 FlagValidator 註解引數中的 value 範圍 this.values = flagValidator.value(); } // 校驗 @Override public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) { boolean isValid = false; // 如果引數沒有傳值則預設是true, 不做檢驗 if(value==null){ //當狀態為空時使用預設值 return true; } // 否則遍歷改引數的 value 看引數值是否在範圍內 for (int item : values) { if (item == value) { isValid = true; break; } } return isValid; } }

三.統一異常處理

//如果返回的為json資料或其它物件,新增該註解
@RestControllerAdvice
//@ControllerAdvice
public class GlobalExceptionHandler {
	
   /**
     * 前端引數提交是json格式時校驗丟擲的異常
     * json格式提交時,採用json資料的資料轉換器進行處理,錯誤時丟擲MethodArgumentNotValidException異常
     */
	// 攔截對應的異常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    // 指明 400 異常碼
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result handlerNotValidException(MethodArgumentNotValidException exception) throws Exception {
    	return handlerNotValidException(exception);
    }

 	/**
     * 僅對於表單提交有效
     * 如果是表單型別的提交,進行引數校驗錯誤時會丟擲BindException異常
     */
    // 攔截對應的異常
    @ExceptionHandler(BindException.class)
    // 指明 400 異常碼
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result  handlerBindException(BindException exception) {
        return handlerNotValidException(exception);
    }
	
	private ResultDTO handlerNotValidException(Exception e){
        BindingResult result;
        if (e instanceof BindException) {
            BindException exception = (BindException) e;
            // 獲取驗證失敗的結果
            result = exception.getBindingResult();
        } else {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e;
            // 獲取驗證失敗的結果
            result = exception.getBindingResult();
        }
        StringBuilder errorMsg =new StringBuilder("校驗失敗:");
        for (FieldError fieldError : result.getFieldErrors()) {
            errorMsg.append(fieldError.getDefaultMessage()).append(", ");
        }
        // 這裡自定義了一個異常碼的列舉,其實值就是一個狀態碼字串
        //return Result.fail(CoreConstants.E_PARAMETER,errorMsg.toString());
        return Result.fail("5002",errorMsg.toString());
    }
}

其中Result是返給前端的封裝類

public class Result<T extends Object>{
    private static final long serialVersionUID = -7387542509934814087L;
    // 成功標誌
    private boolean           success;
    // 狀態碼
    private String            code;
    // 異常訊息
    private String            message;
    // 資料
    private T                 data;
	// xxx 這裡一些方法省略寫了
    public static ResultDTO fail(String code, String msg) {
       ResultDTO result = new ResultDTO(false, null,code, msg);
       return result;
    }
	public ResultDTO(boolean success, Object data, String code, String message) {
        this.data = (T) data;
        this.success = success;
        this.code = code;
        this.message = message;
    }
}

四.效果圖

在這裡插入圖片描述
這裡的message格式可以根據自己的需求進行改造