分组校验
在某些需求中,不同的接口对同一个对象的参数的需求是不同的。
例如:新增接口不需要传入对象id,修改接口需要传入对象的id。如果对象id
是Long类型的,那么我们可以在id上标注@Null表示该参数必须为null,@NotNull表示该参数不能为Null。
@NotNull(message = "修改必须指定id")
@Null(message = "新增不能指定id")
@TableId
private Long id;
这时候我们可以对@NotNull和@Null进行分组。
我们新建两个空的接口进行标注:
public interface AddGroup {
}
public interface UpdateGroup {
}
@NotNull(message = "修改必须指定id",groups = {UpdateGroup.class})
@Null(message = "新增不能指定id",groups = {AddGroup.class})
@TableId
private Long brandId;
在controller层,也需要进行标注该接口属于那个分组下的,在@Validated注解中进行标注。
@PostMapping("/save")
public R save(@Validated({AddGroup.class}) @RequestBody Entity entity) {
entityService.save(entity);
return R.ok();
}
@PostMapping("/update")
public R update(@Validated({UpdateGroup.class})@RequestBody Entity entity) {
entityService.updateById(entity);
return R.ok();
}
这时候,分组校验就会生效。
自定义注解校验
但是有时候需求较为复杂,Jsr303的校验注解已经不够使用了。
例如,某个字段只能传入0,1,2这三个值,我们可以自定义注解。
新建@ListValue注解:
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.wj.common.valid.ListValue.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int[] values() default {};
}
新建该校验注解的校验器:
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation){
int[] values = constraintAnnotation.values();
for(int i : values){
set.add(i);
}
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
在resources目录下新建validationMessages.properties文件:
com.wj.common.valid.ListValue.message=必须包含指定的值
注意,有可能读取出来的properties文件乱码,我们需要手动改一下字符集:
在需要校验的字段上加自定义注解:
@NotNull(groups = {AddGroup.class,UpdateGroup.class})
@ListValue(values={1,0},groups = {AddGroup.class,UpdateGroup.class})
private Integer showStatus;
这时候,自定义注解就会生效。