溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn)

發(fā)布時(shí)間:2020-11-03 14:49:44 來(lái)源:億速云 閱讀:387 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn)?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn)

ValidationApi框架就是用來(lái)解決參數(shù)校驗(yàn)中代碼冗余問(wèn)題,ValidationApi框架提供一些注解用來(lái)幫助我們對(duì)請(qǐng)求參數(shù)進(jìn)行校驗(yàn)。

Maven依賴

<!--參數(shù)校驗(yàn)-->
<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:用于對(duì)枚舉校驗(yàn)的接口

/**
* 用于實(shí)現(xiàn)枚舉類的校驗(yàn)
*/
public interface EnumValidate<T> {

 /**
  * 校驗(yàn)枚舉值是否存在
  */
 boolean existValidate(T value);
}

ActionTypeEnumValid:用于對(duì)枚舉類校驗(yàn)的自定義注解

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

 String message() default "";


 Class<&#63;>[] groups() default {};


 Class<&#63; extends Payload>[] payload() default {};


 Class<&#63;>[] target() default {};

 /**
  * 允許的枚舉
  *
  * @return
  */
 Class<&#63; extends Enum<&#63;>> enumClass();
}

ActionTypeEnumValidator:枚舉校驗(yàn)器

/**
* 用于校驗(yàn)ActionTypeEnumValidator
*/
public class ActionTypeEnumValidator implements ConstraintValidator<ActionTypeEnumValid,String> {


 private Class<&#63; 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");

 /**
  * 狀態(tài)值
  */
 private String couponType;

 /**
  * 狀態(tài)描述
  */
 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;
 }

 /**
  * 判斷是否在枚舉類當(dāng)中
  * @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提供的異常處理機(jī)制,對(duì)ValidationApi的異常進(jìn)行封裝

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

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


 /**
  * 缺少請(qǐng)求體異常處理器
  *
  * @param e 缺少請(qǐng)求體異常
  * @return Response
  */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(HttpMessageNotReadableException.class)
 public ResponseResult parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
  log.error("缺少請(qǐng)求體異常", e);
  return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "參數(shù)體不能為空");
 }


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


 /**
  * 自定義參數(shù)錯(cuò)誤異常處理器
  *
  * @param e 自定義參數(shù)
  * @return ResponseInfo
  */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler({BusinessException.class})
 public ResponseResult paramExceptionHandler(BusinessException e) {
  log.error("業(yè)務(wù)異常", e);
  // 判斷異常中是否有錯(cuò)誤信息,如果存在就使用異常中的消息,否則使用默認(rèn)消息
  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);
  // 判斷異常中是否有錯(cuò)誤信息,如果存在就使用異常中的消息,否則使用默認(rèn)消息
  if (!StringUtils.isEmpty(e.getMessage())) {
   return new ResponseResult(CouponTypeEnum.UNKNOWN_ERROR.getcouponTypeStr(), e.getMessage());
  }
  return new ResponseResult(CouponTypeEnum.UNKNOWN_ERROR);
 }
}

驗(yàn)證

請(qǐng)求的封裝類

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

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

}

請(qǐng)求接口

@Valid 用于開(kāi)啟請(qǐng)求參數(shù)校驗(yàn)

@RestController
@Slf4j
@Api(value = "遠(yuǎn)程調(diào)用模塊")
@RequestMapping("/xiyuanrpc")
public class RPCController {

 @PostMapping("/rpcNettybyInvoke")
 @ApiOperation(value = "rpc遠(yuǎn)程調(diào)用")
 @InvokeParameterCheck
 @MethodLogPrint
 public ResponseResult rpcNettybyInvoke(@Valid @RequestBody CommandPOJO pojo) {
  return NettyClientUtil.rpcNetty(pojo);
 }

}

通過(guò)Knife4j訪問(wèn)對(duì)應(yīng)接口

SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn)

關(guān)于SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn)問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI