自定义校验注解ConstraintValidator
ConstraintValidator新建一个枚举类,限制请求参数中的属性值只能等于枚举中的值
public enum EnumType {
/**
* 数组中是要等于的值每增加一个要校验的类型,
* 增加一个对应枚举类
*/
// 性别
GENDER_TYPE(new String[]{"0", "1"}),
// 年级
GRADE_TYPE(new String[]{"1", "2", "3"});
private String[] values;
EnumType(String[] values) {
this.values = values;
}
public String[] getValues() {
return values;
}
}
新建一个自定义注解
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解
*
* @author
*/
// 指定这个校验注解的实现类
@Constraint(validatedBy = {EnumValidatorImpl.class})
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumValidator {
EnumType value();
/**
* 是否强制校验
*
* @return 是否强制校验的boolean值
*/
boolean required() default true;
/**
* 校验不通过时的报错信息
*
* @return 校验不通过时的报错信息
*/
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
定义校验类,实现ConstraintValidator接口.
接口使用了泛型,需要指定两个参数
- 第一个是自定义注解
- 第二个是需要校验的数据类型
重写2个方法:
- initialize方法主要做一些初始化操作,它的参数是我们使用到的注解,可以获取到运行时的注解信息。
- isValid方法就是要实现的校验逻辑,被注解的对象会传入此方法中。
import org.apache.commons.lang3.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 校验类
* @author
*/
public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, String> {
/**
* 是否强制校验
*/
private boolean required;
private String[] values;
private String message;
/**
* 会在校验实例化后被调用,一般用于做些初始化工作。
*
* @param constraintAnnotation
*/
@Override
public void initialize(EnumValidator constraintAnnotation) {
this.required = constraintAnnotation.required();
this.values = constraintAnnotation.value().getValues();
this.message = constraintAnnotation.message();
}
/**
* 实际执行验证的方法,第一个参数获取的是字段或对象实际对应的值,取决于类的枚举限定类型。
* 第二个参数是ConstraintValidatorContext,上下文可以做些默认的设置。
*
* @param checkValue 要校验的值
* @param constraintValidatorContext
* @return
*/
@Override
public boolean isValid(String checkValue, ConstraintValidatorContext constraintValidatorContext) {
if (required) {
//value就是需要校验的值
//验证
boolean exist = false;
for (String value : values) {
if (value.equals(checkValue)) {
exist = true;
break;
}
}
// 校验未通过,并且message为null
if (StringUtils.isBlank(message) && !exist) {
StringBuilder sb = new StringBuilder();
for (String s : values) {
sb.append(s).append(";");
}
String msg = sb.toString();
msg = msg.substring(0, msg.length() - 1);
// 禁用默认的message的值
constraintValidatorContext.disableDefaultConstraintViolation();
///重新添加错误提示语句
constraintValidatorContext.buildConstraintViolationWithTemplate("value must in:" + msg).addConstraintViolation();
}
return exist;
}
return false;
}
}
创建要校验的实体类
import cn.domin.base.PrinterBaseEntity;
import cn.domin.common.validator.EnumType;
import cn.domin.common.validator.EnumValidator;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
@Data
public class Student extends BaseEntity implements Serializable {
/**
* 性别
*/
@EnumValidator(EnumType.GENDER_TYPE)
private String gender;
/**
* 年级
*/
@EnumValidator(EnumType.GRADE_TYPE)
private String grade;
}
创建接口
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@Slf4j
@RestController
@RequestMapping("/test/")
public class TestController {
@PostMapping("/student/create")
public void createStudent(@RequestBody @Valid Student student) {
}
}
发起请求
如果请求参数属性值和枚举值不同时就会提示
参考资料: