之前写了一个博客是关于使用SpringBoot使用validation-api实现参数校验,当时使用的注解都是validation-api自带的注解只能完成对空值、长度等简单的校验,在我们日常的使用当中会遇到对参数是否在枚举值类的校验,针对这种情况我们怎么来实现呢?
SpringBoot使用validation-api实现参数校验可参考我的博客:SpringBoot使用validation-api实现参数校验
正文SpringBoot使用validation-api实现对枚举类参数校验
ValidationApi框架就是用来解决参数校验中代码冗余问题,ValidationApi框架提供一些注解用来帮助我们对请求参数进行校验。
Maven依赖
javax.validation validation-api2.0.1.Final org.apache.commons commons-lang33.3.2 org.projectlombok lombok1.18.2 true com.github.xiaoymin knife4j-spring-boot-starter2.0.4
EnumValidate:用于对枚举校验的接口
public interface EnumValidate{ 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 {};
Class extends Enum>> enumClass();
}
ActionTypeEnumValidator:枚举校验器
public class ActionTypeEnumValidator implements ConstraintValidator {
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{ 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; } @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 {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MissingServletRequestParameterException.class)
public ResponseResult parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
log.error("参数异常", e);
return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "请求参数 " + e.getParameterName() + " 不能为空");
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseResult parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
log.error("缺少请求体异常", e);
return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "参数体不能为空");
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseResult parameterExceptionHandler(MethodArgumentNotValidException e) {
log.error("参数验证异常", e);
// 获取异常信息
BindingResult exceptions = e.getBindingResult();
// 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
if (exceptions.hasErrors()) {
List 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);
}
@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);
}
@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枚举类参数校验内容请搜索考高分网以前的文章或继续浏览下面的相关文章希望大家以后多多支持考高分网!



