1. 程式人生 > >JAVA引數驗證 Validation(二)分組校驗&自定義校驗

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;
}