自定义注解校验枚举值

前言

传参时候总会遇到各式各样的传参,有些状态传参,0或1,有些不连续的数值传参像1,2, 5,有些传参须符合定义的枚举值等,本文主要重点记录自定义注解校验枚举参数

一、逻辑中枚举校验

private void checkStatus(Integer imgStatus) {
        if (ObjectUtil.isEmpty(BankBannerEnums.STATUS.findByCode(imgStatus))) {
            throw new CustomException(ErrorConstant.INVALID_STATUS);
        }
    }
public class BankBannerEnums {
    public enum STATUS {
        INVALID(0, "无效"),
        VALID(1, "生效");

        private Integer code;
        private String value;

        STATUS(Integer code, String value) {
            this.code = code;
            this.value = value;
        }
        public static BankBannerEnums.STATUS findByCode(Integer code) {
            if (code != null) {
                for (BankBannerEnums.STATUS status : BankBannerEnums.STATUS.values()) {
                    if (status.getCode().intValue() == code) {
                        return status;
                    }
                }
            }
            return null;
        }

        public Integer getCode() {
            return code;
        }

        public void setCode(Integer code) {
            this.code = code;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}


二、连续数字状态枚举校验

直接使用各种注解校验

@Max(value = 1)
@Min(value = 0)
private Integer status;


三、不连续数字自定义注解校验


如果状态是0,1,3 则可以用不连续数字自定义注解校验

// 元注解表示该注解可以用在的地方,此定义注解可以用在属性上
@Target(ElementType.FIELD)
// 元注解被它所注解的注解保留多久
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstrictorMethod.class)
public @interface MyConstraintValidator {

    int [] value();

    String message() default "类型不匹配";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };

}
@Slf4j
public class MyConstrictorMethod implements ConstraintValidator<MyConstraintValidator, Object> {

    private int[] values;

    @Override
    public void initialize(MyConstraintValidator myConstraintValidator) {
        log.info("MyConstraintValidatorMethod 初始化");
        this.values = myConstraintValidator.value();
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        AtomicBoolean atomicValid = new AtomicBoolean(false);
        if (o == null) {
            //当状态为空时使用默认值
            return atomicValid.get();
        }

        for (int value : values) {
            if (value == (Integer) o) {
                atomicValid.set(true);
            }
        }
        return atomicValid.get();
    }
}
@MyConstraintValidator(value = {0,1,3})
  private Integer status;


注意

自测传入integer参数时候是可以传入小数的比如1.5,但是它会自动变为1传入

四、自定义注解校验枚举值

有时候传参值对应的是枚举值,所以就要求传入参数要复合枚举值数据,这种情况也有好多解决方式,上面的三种方法都可以解决,或者也可以直接使用正则注解实现

@Pattern(regexp = "1|3|01|2", message = "入参有误")
private String status;

但是在枚举有变化时,就需要更改注解内容,所以就可以定义注解直接读取枚举进行校验

自定义注解 

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValidator.class})
public @interface EnumValid {

	String message() default "请传入正确的类型";

	Class<?>[] groups() default {};

	Class<? extends Payload>[] payload() default {};
    
    Class<?> target() default Class.class;

}

设置校验规则 

import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Method;

/**
 * @author guang
 * @date 2023/1/8
 **/
@Slf4j
public class EnumValidator implements ConstraintValidator<EnumValid, Object> {

	private EnumValid annotation;

	@Override
	public void initialize(EnumValid constraintAnnotation) {

		annotation = constraintAnnotation;
	}

	@Override
	public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
		boolean result = false;

		// 获取注解时传的target参数
		Class<?> cls = annotation.target();
        //String massage = annotation.massage();
        // 获取这个枚举类中的枚举列表
		Object[] objects = cls.getEnumConstants();
			try {
				// 获取枚举类中的getCode方法对象
				Method method = cls.getMethod("getCode");
				for (Object obj : objects) {
					// obj对象反射调用getCode方法
					Object code = method.invoke(obj);
					// 注解的字段值与枚举实例的code进行比较,一致 则校验通过
					if (value.equals(code)) {
						result = true;
						break;
					}
				}
			} catch (Exception e) {
                log.error("{0}不可用于@EnumValid注解,请查找原因",cls)
                //massage = cls+"不可用于@EnumValid注解,请查找原因";
				result = false;
			}
		return result;
	}

}

 枚举

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

import java.util.stream.Stream;

/**
 * @author guang
 * @date 2023/1/8
 **/
public enum StatusEnum {

	ONE("1","one"),

	TWO("2","two");

	private String code;

	private String desc;

	StatusEnum(Integer code,String desc) {
		this.code = code;
		this.desc = desc;
	}

	@JsonValue
	public Integer getCode() {
		return code;
	}

	public String getDesc() {
		return desc;
	}

}

使用 

import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author guang
 * @date 2023/1/8
 **/
@Data
@NoArgsConstructor
public class TestEntity {

	private Long id;

	@EnumValid(target = StatusEnum.class)
	private String status;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值