1. 程式人生 > 程式設計 >SpringBoot使用validation-api實現對列舉類引數校驗的方法

SpringBoot使用validation-api實現對列舉類引數校驗的方法

前言

之前寫了一個部落格是關於使用SpringBoot使用validation-api實現引數校驗,當時使用的註解都是validation-api自帶的註解只能完成對空值、長度等簡單的校驗,在我們日常的使用當中會遇到對引數是否在列舉值類的校驗,針對這種情況我們怎麼來實現呢?

SpringBoot使用validation-api實現引數校驗可參考我的部落格:SpringBoot使用validation-api實現引數校驗

正文

SpringBoot使用validation-api實現對列舉類引數校驗

ValidationApi框架就是用來解決引數校驗中程式碼冗餘問題,ValidationApi

框架提供一些註解用來幫助我們對請求引數進行校驗。

Maven依賴

<!--引數校驗-->
<dependency>
 <groupId>javax.validation</groupId>
 <artifactId>validation-api</artifactId>
 <version>2.0.1.Final</version>
</dependency>


<!--提供一些字串操作-->
<dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-lang3</artifactId>
 <version>3.3.2</version>
</dependency>


<!--lombok-->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.2</version>
 <optional>true</optional>
</dependency>


<!--knife4j介面-->
<dependency>
 <groupId>com.github.xiaoymin</groupId>
 <artifactId>knife4j-spring-boot-starter</artifactId>
 <version>2.0.4</version>
</dependency>

EnumValidate:用於對列舉校驗的介面

/**
* 用於實現列舉類的校驗
*/
public interface EnumValidate<T> {

 /**
  * 校驗列舉值是否存在
  */
 boolean existValidate(T value);
}

ActionTypeEnumValid:用於對列舉類校驗的自定義註解

@Target({ElementType.FIELD,ElementType.METHOD,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ActionTypeEnumValidator.class})
@Documented
public @interface ActionTypeEnumValid {

 String message() default "";


 Class<?>[] groups() default {};


 Class<? extends Payload>[] payload() default {};


 Class<?>[] target() default {};

 /**
  * 允許的列舉
  *
  * @return
  */
 Class<? extends Enum<?>> enumClass();
}

ActionTypeEnumValidator:列舉校驗器

/**
* 用於校驗ActionTypeEnumValidator
*/
public class ActionTypeEnumValidator implements ConstraintValidator<ActionTypeEnumValid,String> {


 private Class<? extends Enum> enumClass;


 @Override
 public void initialize(ActionTypeEnumValid actionTypeEnumValid) {
  enumClass = actionTypeEnumValid.enumClass();
 }


 @Override
 public boolean isValid(String value,ConstraintValidatorContext context) {
  if (value == null || "".equals(value)) {
   return true;
  }


  EnumValidate[] enums = (EnumValidate[]) enumClass.getEnumConstants();
  if(enums ==null || enums.length == 0){
   return false;
  }


  return enums[0].existValidate(value);
 }

}

ActionTypeEnum:列舉類

@Getter
public enum ActionTypeEnum implements EnumValidate<String> {


 ACTION_INVOKR("invoke","invoke"),UNKNOWN_ERROR("no","no");

 /**
  * 狀態值
  */
 private String couponType;

 /**
  * 狀態描述
  */
 private String couponTypeDesc;

 ActionTypeEnum(String couponType,String couponTypeDesc) {
  this.couponType = couponType;
  this.couponTypeDesc = couponTypeDesc;
 }


 public static String getDescByType(String couponType) {
  for (ActionTypeEnum type : ActionTypeEnum.values()) {
   if (type.couponType.equals(couponType) ) {
    return type.couponTypeDesc;
   }
  }
  return null;
 }

 /**
  * 判斷是否在列舉類當中
  * @param value
  * @return
  */
 @Override
 public boolean existValidate(String value) {
  if (value == null || "".equals(value)) {
   return false;
  }
  for (ActionTypeEnum testEnum : ActionTypeEnum.values()) {
   if (testEnum.getCouponType().equalsIgnoreCase(value)) {
    return true;
   }
  }
  return false;
 }

 public String getcouponTypeStr() {
  return String.valueOf(this.couponType);
 }
}

GlobalExceptionHandler:使用SpringMVC提供的異常處理機制,對ValidationApi的異常進行封裝

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

 /**
  * 忽略引數異常處理器
  *
  * @param e 忽略引數異常
  * @return Response
  */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(MissingServletRequestParameterException.class)
 public ResponseResult parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
  log.error("引數異常",e);
  return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(),"請求引數 " + e.getParameterName() + " 不能為空");
 }


 /**
  * 缺少請求體異常處理器
  *
  * @param e 缺少請求體異常
  * @return Response
  */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(HttpMessageNotReadableException.class)
 public ResponseResult parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
  log.error("缺少請求體異常","引數體不能為空");
 }


 /**
  * 引數效驗異常處理器
  *
  * @param e 引數驗證異常
  * @return ResponseInfo
  */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(MethodArgumentNotValidException.class)
 public ResponseResult parameterExceptionHandler(MethodArgumentNotValidException e) {
  log.error("引數驗證異常",e);
  // 獲取異常資訊
  BindingResult exceptions = e.getBindingResult();
  // 判斷異常中是否有錯誤資訊,如果存在就使用異常中的訊息,否則使用預設訊息
  if (exceptions.hasErrors()) {
   List<ObjectError> errors = exceptions.getAllErrors();
   if (!errors.isEmpty()) {
    // 這裡列出了全部錯誤引數,按正常邏輯,只需要第一條錯誤即可
    FieldError fieldError = (FieldError) errors.get(0);
    return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(),fieldError.getDefaultMessage());
   }
  }
  return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR);
 }


 /**
  * 自定義引數錯誤異常處理器
  *
  * @param e 自定義引數
  * @return ResponseInfo
  */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler({BusinessException.class})
 public ResponseResult paramExceptionHandler(BusinessException e) {
  log.error("業務異常",e);
  // 判斷異常中是否有錯誤資訊,如果存在就使用異常中的訊息,否則使用預設訊息
  if (!StringUtils.isEmpty(e.getMessage())) {
   return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(),e.getMessage());
  }
  return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR);
 }


 /**
  * 其他異常
  *
  * @param e
  * @return
  */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler({Exception.class})
 public ResponseResult otherExceptionHandler(Exception e) {
  log.error("其他異常",e);
  // 判斷異常中是否有錯誤資訊,如果存在就使用異常中的訊息,否則使用預設訊息
  if (!StringUtils.isEmpty(e.getMessage())) {
   return new ResponseResult(CouponTypeEnum.UNKNOWN_ERROR.getcouponTypeStr(),e.getMessage());
  }
  return new ResponseResult(CouponTypeEnum.UNKNOWN_ERROR);
 }
}

驗證

請求的封裝類

/**
* 指令的封裝類
*/
@Getter
@Setter
@ToString
public class CommandPOJO implements Serializable {
 private static final long serialVersionUID = -8497328408069586664L;

 //指令
 @NotNull(message = "指令為必填項,不得為空")
 @ActionTypeEnumValid(message = "該指令暫不支援,暫時只支援invoke",enumClass = ActionTypeEnum.class)
 private String action ="invoke";

}

請求介面

@Valid 用於開啟請求引數校驗

@RestController
@Slf4j
@Api(value = "遠端呼叫模組")
@RequestMapping("/xiyuanrpc")
public class RPCController {

 @PostMapping("/rpcNettybyInvoke")
 @ApiOperation(value = "rpc遠端呼叫")
 @InvokeParameterCheck
 @MethodLogPrint
 public ResponseResult rpcNettybyInvoke(@Valid @RequestBody CommandPOJO pojo) {
  return NettyClientUtil.rpcNetty(pojo);
 }

}

通過Knife4j訪問對應介面

在這裡插入圖片描述

原始碼

專案原始碼可從的我的github中獲取:github原始碼地址

到此這篇關於SpringBoot使用validation-api實現對列舉類引數校驗的方法的文章就介紹到這了,更多相關SpringBoot列舉類引數校驗內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!