JAVA参数验证 Validation(二)分组校验&自定义校验

有些时候一个对象会在多个场景使用,不同场景对该对象中的参数校验需求不同,即有些场景不对参数进行校验。
比如注册时,我们要填写出生日期参数,但是登录时并不需要该参数

这里可以用到校验分组groups

public class User implements Serializable {

    // 添加2个空接口,用例标记参数校验规则
    /**
     * 注册校验规则
     */
    public interface UserRegisterValidView {
    }

    /**
     * 登录校验规则
     */
    public interface UserLoginValidView {
    }

    private static final long serialVersionUID = 1L;

    @NotBlank(message = "用户名不能为空")
    private String userName;

    @NotBlank(message = "密码不能为空")
    private String password;

    // 若填写了groups,则该参数验证只在对应验证规则下启用
    @Past(groups = { UserRegisterValidView.class }, message = "出生日期不符合要求")
    private Date birthday;

    @DecimalMin(value = "0.1", message = "金额最低为0.1")
    @NotNull(message = "金额不能为空")
    private BigDecimal balance;

    @AssertTrue(groups = { UserRegisterValidView.class, UserLoginValidView.class }, message = "标记必须为true")
    private boolean flag;

    @Min(value = 18, message = "年龄不能小于18")
    private Integer age;
}

首先在声明2个空接口,用来标记不同的校验场景

    // 添加2个空接口,用例标记参数校验规则
    /**
     * 注册校验规则
     */
    public interface UserRegisterValidView {
    }

    /**
     * 登录校验规则
     */
    public interface UserLoginValidView {
    }

例如出生日期参数,我们只在注册场景校验,我们在其他场景(包含default)一律不进行验证

    // 若填写了groups,则该参数验证只在对应验证规则下启用
    @Past(groups = { UserRegisterValidView.class }, message = "出生日期不符合要求")
    private Date birthday;

此时的Controller改成

@RequestMapping(value = "/register", method = RequestMethod.POST)
    @ResponseBody//表明对User对象的校验,启用UserRegisterValidView规则
    public CommonResponse register(@Validated(value = { UserRegisterValidView.class }) @RequestBody User user) {
        CommonResponse response = new CommonResponse();
        return response;
    }

如果遇到JAR包中没有的验证规则,那么我们需要自定义校验规则:
首先新建个自定义的校验接口(判断是否为QQ邮箱):

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = IsQQEmailImpl.class) // 指明自定义注解的实现类
public @interface IsQQEmail {

    String message() default "email is invalid";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    public @interface List {
        IsQQEmail[] value();
    }
}

接着写个实现类,实现上面的接口:

public class IsQQEmailImpl implements ConstraintValidator<IsQQEmail, String> {

    @Override
    public void initialize(IsQQEmail isQQEamil) {
        // TODO Auto-generated method stub
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // TODO Auto-generated method stub

        if (value == null) {
            return false;
        }

        // 进行QQ邮箱格式的简单判断,实际开发用正则
        if (value.endsWith("@qq.com") || value.endsWith("@QQ.COM")) {
            return true;
        }

        return false;

    }

}

最后在需要校验的对象属性,添加这个校验注解即可:

public class User implements Serializable {
    @IsQQEmail(message = "邮箱错误")
    private String email;
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页