JSR303 在 Springs 示例中基于注释的验证

将任何 JSR 303 实现添加到类路径中。流行的一种是来自 Hibernate 的 Hibernate 验证器。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>4.2.0.Final</version>
</dependency>

让我们说有一个 rest api 来在系统中创建用户

@RequestMapping(value="/registeruser", method=RequestMethod.POST)
public String registerUser(User user);

输入的 json 样本如下所示

{"username" : "abc@abc.com", "password" : "password1", "password2":"password1"}

User.java

public class User {

    private String username;
    private String password;
    private String password2;

    getXXX and setXXX

}

我们可以在 User Class 上定义 JSR 303 验证,如下所示。

public class User {

    @NotEmpty
    @Size(min=5)
    @Email
    private String username;
    
    @NotEmpty
    private String password;
    
    @NotEmpty
    private String password2;

}

我们可能还需要有一个像 password 和 password2(确认密码)相同的商业验证器,为此我们可以添加一个自定义验证器,如下所示。编写自定义注释以注释数据字段。

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface GoodPassword {
    String message() default "Passwords wont match.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

编写 Validator 类以应用验证逻辑。

public class PastValidator implements ConstraintValidator<GoodPassword, User> {
    @Override
    public void initialize(GoodPassword annotation) {}
    
    @Override
    public boolean isValid(User user, ConstraintValidatorContext context) {
        return user.getPassword().equals(user.getPassword2());
    }
}

将此验证添加到用户类

@GoodPassword
public class User {

    @NotEmpty
    @Size(min=5)
    @Email
    private String username;
    
    @NotEmpty
    private String password;
    
    @NotEmpty
    private String password2;
}

@Valid 在 Spring 中触发验证。BindingResult 是一个由 spring 注入的对象,它在验证后有错误列表。

public String registerUser(@Valid User user, BindingResult result);

JSR 303 注释具有消息属性,可用于提供自定义消息。

@GoodPassword
public class User {

    @NotEmpty(message="Username Cant be empty")
    @Size(min=5, message="Username cant be les than 5 chars")
    @Email(message="Should be in email format")
    private String username;
    
    @NotEmpty(message="Password cant be empty")
    private String password;
    
    @NotEmpty(message="Password2 cant be empty")
    private String password2;

}