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;

}