文章

自定义注解实现参数校验,并实现多参数联动校验

自定义注解实现参数校验,并实现多参数联动校验

Spring Boot中自定义注解实现参数校验

在日常开发中, 我们经常需要用到参数校验,而如果在Controller层中对每个参数都手动代码去校验,无疑是非常繁琐且不易于维护的。而javax正好提供了很多常用的校验,如:@NotNull、@NotBlank、@NotEmpty等常用的参数校验注解,我们只需要在对用的参数上添加该注解就可以完成校验。但是还有很多情况是javax中没有提供的,这时就需要我们自己定义注解来实现响应的参数校验

新建一个注解 @Blank

1
@Documented@Constraint(validatedBy = {BlankValidator.class})@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})@Retention(RUNTIME)public @interface Blank {    String message() default "{javax.validation.constraints.Blank.message}";    Class<?>[] groups() default {};    Class<? extends Payload>[] payload() default {};}

校验一个字段必须为Blank,即:null、空串、trim后为空串

创建对应的 validator

创建 BlankValidator 并实现 ConstraintValidator 的 isValid 方法

1
public class BlankValidator implements ConstraintValidator<Blank, String> {    @Override    public boolean isValid(String value, ConstraintValidatorContext context) {        return StrUtil.isBlank(value);    }}

使用

在接收参数对象中,使用该注解

1
@Blank(message = 'name must be blank')private String name;

多字段联动校验

在参数校验时,很多情况下,需要对多个字段联动判断,如:我们需要传入级别 level 和对应的 code 来做查询,但限制 level 和 code 必须同时存在或者同时不存在,此时可以通过指定 group 来进行分组判断

1
// 指定对应的Provider@GroupSequenceProvider(LevelAndCodeProvider.class)public class TestReq {    @ApiModelProperty(value = "等级")    private String level;    @Blank(message = "等级为空时,code 应同时为空", groups = {WhenLevelIsBlank.class})    @NotBlank(message = "等级不空时,code 不应为空", groups = {WhenLevelNotBlank.class})    @ApiModelProperty(value = "节点id")    private String code;    /* 分组校验 */    public @interface WhenLevelIsBlank {    }    /* 分组校验 */    public @interface WhenLevelNotBlank {    }}
1
public class LevelAndCodeProvider implements DefaultGroupSequenceProvider<TestReqVO> {    @Override    public List<Class<?>> getValidationGroups(TestReqVO object) {        List<Class<?>> defaultGroupSequence = new ArrayList<>();        // 这一步不能省,否则 Default 分组都不会执行了,会抛错的        defaultGroupSequence.add(TestReqVO.class);        if (object != null) { // 这块判空请务必要做            String level = object.getLevel();            if (StrUtil.isBlank(level)) {                defaultGroupSequence.add(TestReqVO.WhenLevelIsBlank.class);            } else {                defaultGroupSequence.add(TestReqVO.WhenLevelNotBlank.class);            }        }        return defaultGroupSequence;    }}

通过分组校验实现,当 level 为空时,code必须为空,当 level 不空时,code 也必须不空

本文由作者按照 CC BY 4.0 进行授权