• tool


    之前会根据业务,自定义注解和扩展validation的校验器来实现基于注解进行通用校验。后面某一天想能不能整个枚举校验- -

    注解定义:

    /**
     * 枚举校验 标识注解
     * @Author:cyw
     * @CreateTime: 2020年11月7日14:14:25
     **/
    @Target({FIELD, PARAMETER})
    @Retention(RUNTIME)
    @Documented
    @Constraint(validatedBy = CheckEnumLegalValidator.class)
    public @interface CheckEnumLegal {
    
        String message() default "非法类型值";
    
        Class<? extends Enum<?>> enumClass();
    
        /**
         * 1、强制方法返回值为Boolean
         * 2、强制方法为静态方法
         * 3、默认校验方法名 validate,后续自己设置
         * 4、entity数据类型要和validate方法参数数据类型要一致 !
         * 5、调用validate方法时,不能抛出异常...
         * 6、最好在枚举类的validate方法上,加上 @CannotDelete 注解标识下...避免被删除 {@link CannotDelete}
         */
        String checkLegalMethodName() default "validate";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }
    

    另一个标识注解定义- -

    /**
     * 该注解标注的地方,不要删除[即使没有任何调用链路]
     * 敬畏之心...
     * @Author:cyw
     * @CreateTime: 2020/12/15 11:46
     **/
    public @interface CannotDelete {
    }
    

    validation校验器

    /**
     * 枚举校验 校验器
     * @Author:cyw
     * @CreateTime: 2020/11/11 15:00
     **/
    public class CheckEnumLegalValidator implements ConstraintValidator<CheckEnumLegal, Object> {
    
        private Class<? extends Enum<?>> enumClass;
        private String enumMethod;
    
    
        @Override
        public void initialize(CheckEnumLegal constraintAnnotation) {
            enumClass = constraintAnnotation.enumClass();
            enumMethod = constraintAnnotation.checkLegalMethodName();
        }
    
        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
    
            if (isAnyNull(value, enumClass, enumMethod)) {
                return true;
            }
    
            Class<?> valueClass = value.getClass();
    
            try {
                Method method = enumClass.getMethod(enumMethod, valueClass);
                if (!Boolean.TYPE.equals(method.getReturnType()) && !Boolean.class.equals(method.getReturnType())) {
                    throw new RuntimeException(enumClass + "类中" + enumMethod + "方法返回不是Boolean值");
                }
    
                if(!Modifier.isStatic(method.getModifiers())) {
                    throw new RuntimeException(enumClass + "类中" + enumMethod + "方法不是静态方法");
                }
                method.setAccessible(true);
                Boolean result = (Boolean)method.invoke(null, value);
                return result == null ? false : result;
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                if (e instanceof InvocationTargetException){
                    throw new ConstraintDeclarationException(((InvocationTargetException) e).getTargetException().getMessage());
                }
                throw new RuntimeException(e);
            }
        }
    }
    

    枚举定义示范

    /**
     * 佣金结算类型
     *
     * @Author:cyw
     * @CreateTime: 2021/1/15 16:39
     */
    @Getter
    @AllArgsConstructor
    public enum CommissionSettlementTypeEnum {
        /**
         * 结算类型 1 xxx
         */
        XXX(Byte.valueOf("1"), "xxx"),
        ;
    
        /**
         * 字段数值
         */
        private final Byte value;
        /**
         * 字段描述
         */
        private final String description;
    
        private static final Map<Byte, CommissionSettlementTypeEnum> MAP = new HashMap<>(values().length);
    
        static {
            for (CommissionSettlementTypeEnum enumItem : values()) {
                MAP.put(enumItem.value, enumItem);
            }
        }
    
        public static CommissionSettlementTypeEnum of(Byte value) {
            BaseUtils.isNullThr(value, "类型不能为空");
    
            CommissionSettlementTypeEnum enumItem = MAP.get(value);
            BaseUtils.isNullThr(enumItem, "CommissionSettlementType 非法类型值 [" + value + "]");
    
            return enumItem;
        }
    
        @CannotDelete
        public static Boolean validate(Byte code) {
        	return BaseUtils.isNull(code) ? false : CommissionSettlementTypeEnum.of(code) != null;
        }
    
    
    }
    
    

    在VO对象中使用示范

    @Data
    @Accessors(chain = true)
    @EqualsAndHashCode(callSuper = false)
    public class XxxCreateVO implements Serializable {
    	private static final long serialVersionUID = -17987079543000987L;
    
    	xxx
    
    	/**
         * 佣金码结算类型
         * @see xxx.CommissionSettlementTypeEnum#value
         */
        @CheckEnumLegal(enumClass = CommissionSettlementTypeEnum.class, message = "结算类型 非法类型值")
        @NotNull(message = "结算类型 不能为空")
        private Byte settlementType;
    
    	xxx	
    
    }
    

    controller使用

    @Validated
    @RestController
    @RequestMapping("/xxx")
    public class XxxController {
    	@PostMapping
        public Response<Long> create(@Valid @RequestBody XxxCreateVO vo) {
        	xxxxx
        }
    }
    
  • 相关阅读:
    吉哥系列故事――恨7不成妻
    K
    F
    树状数组
    34.在排序数组中查找元素的第一个和最后一个位置--二分查找
    CSS选择器及其权重
    CSS布局 圣杯和双飞翼
    983. 最低票价 -- 动态规划
    合并k个排序链表 二分
    面试题 16.03. 交点
  • 原文地址:https://www.cnblogs.com/chenyiwu/p/14413714.html
Copyright © 2020-2023  润新知