> 文章列表 > 自定义javax.validation校验枚举类

自定义javax.validation校验枚举类

自定义javax.validation校验枚举类

枚举类单一情况

package com.archermind.cloud.phone.dto.portal.external.validation.validator;import com.archermind.cloud.phone.dto.portal.external.validation.constraints.EnumValidation;
import lombok.extern.slf4j.Slf4j;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Method;/*** 枚举类型校验类** @author cyc* @version 2022/10/18 0018* @see [相关类/方法]* @since [cloud-phone-baseline]*/
@Slf4j
public class EnumValidator implements ConstraintValidator<EnumValidation, Object>
{private EnumValidation annotation;/*** Initializes the validator in preparation for* {@link #isValid(Object, ConstraintValidatorContext)} calls.* The constraint annotation for a given constraint declaration* is passed.* <p>* This method is guaranteed to be called before any use of this instance for* validation.* <p>* The default implementation is a no-op.** @param constraintAnnotation annotation instance for a given constraint declaration*/@Overridepublic void initialize (EnumValidation constraintAnnotation){this.annotation = constraintAnnotation;}/*** Implements the validation logic.* The state of {@code value} must not be altered.* <p>* This method can be accessed concurrently, thread-safety must be ensured* by the implementation.** @param value   object to validate* @param context context in which the constraint is evaluated* @return {@code false} if {@code value} does not pass the constraint*/@Overridepublic boolean isValid (Object value, ConstraintValidatorContext context){if (value == null){return annotation.optional ();}Object[] objects = annotation.enumClass ().getEnumConstants ();try{Method method = annotation.enumClass ().getMethod (annotation.method ());for (Object o : objects){if (value.equals (method.invoke (o))){return true;}}}catch (Exception e){log.info ("EnumValidator catch en exception: ", e);return false;}return false;}
}

EnumValidation

package com.archermind.cloud.phone.dto.portal.external.validation.constraints;import com.archermind.cloud.phone.dto.portal.external.validation.validator.EnumValidator;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** 枚举类校验注解,用于接口参数校验使用* 可用于对象字段** @author cyc* @version 2022/10/18 0018* @see [自定义注解]* @since [cloud-phone-baseline]*/
@Target ({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention (RUNTIME)
@Documented
@Repeatable (EnumValidation.List.class)
@Constraint (validatedBy = { EnumValidator.class })
public @interface EnumValidation
{String message () default "Invalid enum value";Class<?> enumClass ();Class<?>[] groups () default {};Class<? extends Payload>[] payload () default {};String method () default "getType";boolean optional () default false;/*** Defines several {@link EnumValidation} annotations on the same element.** @see EnumValidation*/@Documented@Target ({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention (RUNTIME)@interface List{EnumValidation[] value ();}
}

使用

/*** <一句话功能简述> <功能详细描述>** @author cyc* @version 2023/3/8* @see [相关类/方法]* @since [Operator.java]*/
@Slf4j
@AllArgsConstructor
@Getter
public enum ProductTypeEnum
{//续费续约类型CPH ("CPH", "云手机"),STB ("STB", "云魔百盒");private final String type;private final String message;
}

使用类

@Data
public class ProductCreateReq implements Serializable
{
/*** 产品类型(Y)* CPH:云手机* STB:云魔百盒*/@NotBlank (message = "产品类型不能为空")@EnumValidation (enumClass = ProductTypeEnum.class, optional = true, message = "产品类型枚举类不正确")private String type;
}

当前端传递过来多个类型:例如:aa;bb

package com.archermind.cloud.phone.dto.portal.external.validation.constraints;import com.archermind.cloud.phone.dto.portal.external.validation.validator.StringEnumValidator;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** 枚举类校验注解,用于接口参数校验使用* 可用于对象字段** @author cyc* @version 2022/10/18 0018* @see [自定义注解]* @since [cloud-phone-baseline]*/
@Target ({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention (RUNTIME)
@Documented
@Repeatable (StringEnumValidation.List.class)
@Constraint (validatedBy = { StringEnumValidator.class })
public @interface StringEnumValidation
{String message () default "Invalid enum value";Class<?> enumClass ();Class<?>[] groups () default {};Class<? extends Payload>[] payload () default {};String method () default "getType";boolean optional () default false;/*** Defines several {@link StringEnumValidation} annotations on the same element.** @see StringEnumValidation*/@Documented@Target ({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention (RUNTIME)@interface List{StringEnumValidation[] value ();}
}

StringEnumValidator

package com.archermind.cloud.phone.dto.portal.external.validation.validator;import com.archermind.cloud.phone.dto.portal.external.validation.constraints.StringEnumValidation;
import lombok.extern.slf4j.Slf4j;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.List;/*** 枚举类型校验类** @author cyc* @version 2022/10/18 0018* @see [相关类/方法]* @since [cloud-phone-baseline]*/
@Slf4j
public class StringEnumValidator implements ConstraintValidator<StringEnumValidation, String>
{private StringEnumValidation annotation;/*** Initializes the validator in preparation for* {@link #isValid(String, ConstraintValidatorContext)} calls.* The constraint annotation for a given constraint declaration* is passed.* <p>* This method is guaranteed to be called before any use of this instance for* validation.* <p>* The default implementation is a no-op.** @param constraintAnnotation annotation instance for a given constraint declaration*/@Overridepublic void initialize (StringEnumValidation constraintAnnotation){this.annotation = constraintAnnotation;}/*** Implements the validation logic.* The state of {@code value} must not be altered.* <p>* This method can be accessed concurrently, thread-safety must be ensured* by the implementation.** @param value   object to validate* @param context context in which the constraint is evaluated* @return {@code false} if {@code value} does not pass the constraint*/@Overridepublic boolean isValid (String value, ConstraintValidatorContext context){if (value == null || value.equals ("")){return annotation.optional ();}Object[] objects = annotation.enumClass ().getEnumConstants ();List<String> dest = new ArrayList<> ();for (Object object : objects){dest.add (object.toString ());}try{String[] split = value.split (";");for (String s : split){if (! dest.contains (s)){return false;}}}catch (Exception e){log.info ("EnumValidator catch en exception: ", e);return false;}return true;}
}

使用

/*** 购买类型** @author cyc* @version 2023/3/9* @see [相关类/方法]* @since [Operator.java]*/
@Slf4j
@AllArgsConstructor
@Getter
public enum ProductItemOrderTypeEnum
{TRY ("TRY", "试用"),RENEW ("RENEW", "续费"),EXCHANGE_BUY ("EXCHANGE_BUY", "兑换购买"),EXCHANGE_RENEW ("EXCHANGE_RENEW", "利用兑换码续订"),BUY ("BUY", "购买");private final String type;private final String message;
}

@Data
public class ProductItemCreateReq implements Serializable
{
/*** 购买类型* TRY:试用* BUY:购买* RENEW:续费* EXCHANGE_BUY:兑换购买* EXCHANGE_RENEW:利用兑换码续订* (可以多选,用英文分号分隔,例如:BUY;RENEW)* 为空则表示不限制*/@StringEnumValidation (enumClass = ProductItemOrderTypeEnum.class, optional = true, message = "购买类型枚举类不正确")private String orderType;
}