前面介绍了Java Bean Validation的使用,本文进一步介绍一下当标准的校验注解不满足要求时,可以自定义校验注解满足特定需求。比如
@In
,要求参数数据某个固定的集合(类似于枚举值)
- Java Bean Validation的初步使用
- Java Bean Validation自定义注解
- Java Bean Validation分组校验
- Java Bean Validation校验@PathVariable和@RequestParam
自定义注解
@In
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Constraint(validatedBy = InValidator.class)
@Target({java.lang.annotation.ElementType.FIELD})
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Documented
public @interface In {
//提示信息,可以写死,可以填写国际化的key
String message() default "";
int[] values() default {};
//下面这两个属性必须添加
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
注解实现类
InValidator
public class InValidator implements ConstraintValidator<In, Integer> {
private final Set<Integer> values = new HashSet<>();
private String msg = null;
@Override
public void initialize(In constraintAnnotation) {
for (int value : constraintAnnotation.values()) {
this.values.add(value);
}
String msg = values.stream().map(Object::toString).collect(Collectors.joining(",", "[", "]"));
this.msg = String.format("只能取值%s", msg);
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
boolean contains = values.contains(value);
if (contains) {
return true;
}
if (context.getDefaultConstraintMessageTemplate().isEmpty()) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(this.msg).addConstraintViolation();
}
return false;
}
}
使用
Person.java
@Data
public class Person {
@Null(message = "id should be empty")
private Integer id;
@Length(min = 2, max = 10, message = "name的长度为[2-10]之间")
@NotBlank(message = "name should not be empty")
private String name;
@Min(18)
@Max(130)
private Integer age;
@NotNull(message = "gender should not be empty")
private Boolean gender;
@Null(message = "createTime should be empty")
private LocalDateTime createTime;
@Null(message = "updateTime should be empty")
private LocalDateTime updateTime;
//这里是自定义注解,指定type只能是1或2
@In(values = {1,2})
private Integer type;
}
测试
- 参数
{
"name": "tenmao",
"gender": true,
"type": 3
}
- 结果
{
"code": 400,
"msg": "[只能取值[1,2]]",
"data": null
}
常见问题
- 自定义注解需要配置
@Constraint(validatedBy = InValidator.class)
,但是查看内置的注解,比如@NotNull
中的却是空的validatedBy = {}
。这是因为API中并不包含实现类,这样就需要实现类实现手动配置,比如hibernate-validator是在ConstraintHelper.java
完成的
网友评论