Spring Validation的校验顺序问题

5,096 阅读1分钟

问题描述

@Data
public class RegisterForm {

    @Length(min = 4, message = "用户名长度至少4位")
    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    @Length(max = 20, message = "密码长度最多20位")
    @Length(min = 8, message = "密码长度至少8位")
    @Pattern(regexp = "^[\\w_-]{8,20}$", message = "密码格式错误")
    private String password;

    @NotBlank(message = "学号不能为空")
    @Length(min = 9, max = 10, message = "学号不正确")
    private String sno;

}

上述代码检验顺序,若参数全为空,注解全部命中,会随机返回校验错误信息。

也就是BindingResult#getAllErrors()获取到的ObjectError的顺序是随机的

解决方法

添加多个GroupX,并加入到@GroupSequence中,按需要的顺序添加到校验注解的group属性中,同时为Controller的方法中的@Validatedvalue属性中添加Group.class

// GroupA.java
public interface GroupA {}

// GroupB.java
public interface GroupB {}

// GroupC.java
public interface GroupC {}

// GroupD.java
public interface GroupD {}

// GroupE.java...

// Group.java
@GroupSequence({GroupA.class, GroupB.class, GroupC.class, GroupD.class, ...})
public interface Group {}
@Data
public class RegisterForm {

    @Length(min = 4, message = "用户名长度至少4位", group = GroupA.class)
    @NotBlank(message = "用户名不能为空", group = GroupB.class)
    private String username;

    @NotBlank(message = "密码不能为空", group = GroupC.class)
    @Length(max = 20, message = "密码长度最多20位", group = GroupD.class)
    @Length(min = 8, message = "密码长度至少8位", group = GroupD.class)
    @Pattern(regexp = "^[\\w_-]{8,20}$", message = "密码格式错误", group = GroupE.class)
    private String password;

}

    @PostMapping("register")
    public Response register(@RequestBody @Validated(Group.class) RegisterForm form) {
        //...
    }