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;
}
}
网友评论