美文网首页
参数规则校验-限定枚举值的校验

参数规则校验-限定枚举值的校验

作者: 木果渣 | 来源:发表于2019-03-01 14:27 被阅读0次
    api中,有个字段为订单状态,限定为“开启”和“关闭”,不满足条件了一律不接受。要实现,可以在处理方法中增加条件判断,但是如何做的通用一点呢?🤭或许可以用validation试一下。
    

    首先,定义一个基础的枚举接口,只要实现了此接口的枚举方可校验枚举值。

    public interface BaseIntEnum {
    
        Integer getCode();
    
        String getDesc();
    }
    

    接下来定义我们自己的枚举值

    public enum OrderStatusEnum implements BaseIntEnum{
    
        OPEN(1,"开启"),
        CLOSE(2, "关闭");
    
        private Integer code;
        private String desc;
    
        OrderStatusEnum(int code, String desc){
            this.code = code;
            this.desc = desc;
        }
        public Integer getCode() {
            return code;
        }
    
        public String getDesc() {
            return desc;
        }
    
    }
    

    定义枚举校验注解

    @Target( { METHOD, FIELD, ANNOTATION_TYPE })
    @Retention(RUNTIME)
    @Constraint(validatedBy = CheckEnumValidator.class)
    @Documented
    public @interface CheckEnum {
        String message() default "枚举不合规范";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
        Class<?> enumClass();
    }
    

    然后是枚举校验器

    public class CheckEnumValidator implements ConstraintValidator<CheckEnum, Integer> {
        private Class<?> enumClass;
    
        @Override
        public void initialize(CheckEnum constraintAnnotation) {
            enumClass = constraintAnnotation.enumClass();
        }
    
        @Override
        public boolean isValid(Integer value, ConstraintValidatorContext context) {
            Type[] types = enumClass.getGenericInterfaces();
            if (!needValidate(types)) {
                return true;
            }
            try {
                return validate(value);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            return false;
        }
    
        /**
         * 是否需要校验
         * 只有implements接口BaseIntEnum,才能校验
         * @return
         */
        private boolean needValidate(Type[] types){
            boolean needValidate = false;//是否需要校验
            for (Type type : types) {
                if (type.getTypeName().equals(BaseIntEnum.class.getName())) {
                    needValidate = true;
                }
            }
            return needValidate;
        }
    
        /**
         * 遍历枚举code值,校验value是否存在其中
         * @param value
         * @return
         * @throws NoSuchMethodException
         * @throws InvocationTargetException
         * @throws IllegalAccessException
         */
        private boolean validate(Integer value) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            Method valuesMethod = enumClass.getMethod("values");
            if (null == valuesMethod) {
                return true;
            }
            BaseIntEnum inter[] = (BaseIntEnum[]) valuesMethod.invoke(null);
            for(BaseIntEnum iter : inter){
                if(iter.getCode().equals(value)){
                    return true;
                }
            }
            return false;
        }
    }
    

    最后,写个实体类验证一下

    @Getter
    @Setter
    public class EnumDTO {
        @CheckEnum(enumClass = OrderStatusEnum.class)
        Integer orderStatus;
    }
    
     public static void main(String[] args) {
            EnumDTO enumDTO = new EnumDTO();
            enumDTO.setOrderStatus(3);
            ValidateCheckUtils.check(enumDTO);
        }
    

    此方法比较通用,只要实现了BaseIntEnum接口的枚举类,都可以被校验,但也局限。code必须为Integer类型,如果为String类型,需要重新定义接口,并重写枚举注解和校验器。一般实际生产中,字符串用的比较多。

    后续:我有点傻,直接把基础枚举改为这样就不纠结是int还是String了。

    @Getter
    @Setter
    public class EnumDTO {
    
        @CheckEnum(enumClass = OrderStatusEnum.class)
        Integer orderStatus;
    }
    

    相关文章

      网友评论

          本文标题:参数规则校验-限定枚举值的校验

          本文链接:https://www.haomeiwen.com/subject/itsduqtx.html