JAVA引數驗證 Validation(二)分組校驗&自定義校驗
阿新 • • 發佈:2019-02-12
有些時候一個物件會在多個場景使用,不同場景對該物件中的引數校驗需求不同,即有些場景不對引數進行校驗。
比如註冊時,我們要填寫出生日期引數,但是登入時並不需要該引數
這裡可以用到校驗分組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;
}