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
    }
}
原文地址:https://www.cnblogs.com/chenyiwu/p/14413714.html