美文网首页
自定义javax.validation校验枚举类

自定义javax.validation校验枚举类

作者: Muscleape | 来源:发表于2020-03-20 17:08 被阅读0次

    1、javax.validation中定义了大量的校验方法,能校验从页面接收到的数据;
    2、但是对应对于枚举值的校验却没有,需要自己实现一个;
    (例如:男女性别字段的值只能是1/2,状态值只能是1、2、3这三种情况)
    3、创建过程:a.创建一个自定义注解【EnumValidation】;b.创建一个枚举类校验器【EnumValidator】

    1、自定义的注解【EnumValidation】

    package com.muscleape.annotation;
    
    import com.muscleape.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;
    
    /**
     * To validate a enum's value is right or not .
     * <p>
     * example one, if a enum like
     * <code>
     * public enum Sex {
     * <p>
     * MALE, FEMALE, OTHER
     * }
     * </code>
     * can use the annotation as <code>@Enum(clazz = Sex.class)</code>, and param sex = 0;
     * Or use the annotation as <code>@Enum(clazz = Sex.class, method = "name")</code>,
     * and param sex = "MALE";
     * <p>
     * example two, if a enum like
     * <code>
     * public enum Role {
     * <p>
     * ADMIN(1, "ADMIN"),
     * TEST(2, "TEST"),
     * DEVELOP(3, "DEVELOP");
     * <p>
     * private int value;
     * private String desc;
     * <p>
     * Role(int value, String desc) {
     * this.value = value;
     * this.desc = desc;
     * }
     * <p>
     * public int getValue() {
     * return value;
     * }
     * <p>
     * public void setValue(int value) {
     * this.value = value;
     * }
     * <p>
     * public String getDesc() {
     * return desc;
     * }
     * <p>
     * public void setDesc(String desc) {
     * this.desc = desc;
     * }
     * }
     * </code>
     * can use the annotation as <code>@Enum(clazz = Role.class, method = "getValue")</code>,
     * and param role = 1; Or use the annotation as <code>@Enum(clazz = Role.class,
     * method = "getDesc")</code>,and param role = "ADMIN";
     *
     * @author Muscleape
     * @ClassName EnumValidate.java
     * @Description Controller入参对象中属性枚举项校验
     * @createTime 2020年03月18日 14:45:00
     */
    @Documented
    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RUNTIME)
    @Repeatable(EnumValidation.List.class)
    @Constraint(validatedBy = {EnumValidator.class})
    public @interface EnumValidation {
        String message() default "{*.validation.constraint.Enum.message}";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
        /**
         * the enum's class-type
         *
         * @return Class
         */
        Class<?> clazz();
    
        /**
         * the method's name ,which used to validate the enum's value
         *
         * @return method's name
         */
        String method() default "ordinal";
    
        /**
         * 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();
        }
    }
    
    

    2、自定义枚举类校验器【EnumValidator】

    package com.muscleape.validator;
    
    import com.muscleape.annotation.EnumValidation;
    
    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    import java.lang.reflect.Method;
    
    /**
     * @author Muscleape
     * @ClassName EnumValidator.java
     * @Description Controller入参对象中属性枚举项校验
     * @createTime 2020年03月18日 14:51:00
     */
    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
         */
        @Override
        public 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
         */
        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            if (value == null) {
                return false;
            }
    
            Object[] objects = annotation.clazz().getEnumConstants();
            try {
                Method method = annotation.clazz().getMethod(annotation.method());
                for (Object o : objects) {
                    if (value.equals(method.invoke(o))) {
                        return true;
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return false;
        }
    }
    

    3、 使用

    package com.olayc.engine.ui.controller.manager.invoice;
    
    import com.alibaba.fastjson.JSON;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Controller;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Created by Weigang Wu on 2018/8/1.
     */
    @Controller
    @RequestMapping("muscleape/test")
    public class EnumValidationController {
    
        /**
         * 发票冲红操作
         *
         * @return
         * @author Muscleape
         * @params
         * @updateTime 2020/3/18 13:47
         */
        @RequestMapping("testValidation")
        @ResponseBody
        public void testValidation(@Validated testValidation model) {
            return "";
        }
    
    }
    
    package com.muscleape.model;
    
    import com.muscleape.annotation.EnumValidation;
    import com.muscleape.enums.*;
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.io.Serializable;
    
    /**
     * @author Muscleape
     * @ClassName TestModel.java
     * @Description 
     * @createTime 2020年03月18日 13:52:00
     */
    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public class TestModel implements Serializable {
        private static final long serialVersionUID = 6653149665302552059L;
    
        /**
         * 环境:0:开发;1:测试;2:UAT;3:生产
         */
        @EnumValidation(clazz = EnvironmentEnum.class, method = "getKey", message = "环境类型无效")
        private Integer invoiceTitleType;
    }
    
    package com.muscleape.enums;
    
    import lombok.Getter;
    
    /**
     * @author Muscleape
     * @ClassName EnvironmentEnum.java
     * @Description 环境类型
     * @createTime 2020年03月18日 15:01:00
     */
    @Getter
    public enum EnvironmentEnum {
    
        DEV(0, "开发"),
        TEST(1, "测试"),
        UAT(2, "UAT"),
        PROD(3, "生产");
    
        private final int key;
        private final String name;
    
        EnvironmentEnum(int key, String name) {
            this.key = key;
            this.name = name;
        }
    
    }
    

    相关文章

      网友评论

          本文标题:自定义javax.validation校验枚举类

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