文檔: http://beanvalidation.org/1.1/spec/
API : http://docs.jboss.org/hibernate/beanvalidation/spec/1.1/api/
http://blog.sina.com.cn/s/blog_a3d2fd2d0101hyu7.html
http://haohaoxuexi.iteye.com/blog/1812584
JSR303是JAVA EE6中的子規范。用於對Java Bean的字段值進行校驗,確保輸入進來的數據在語義上是正確的,使驗證邏輯從業務代碼中脫離出來。JSR303是運行時數據驗證框架,驗證之后驗證的錯誤信息會馬上返回。有兩個版本JSR303(BeanValidation1.0)和JSR349(BeanValidation1.1)。
javax.validation:validation-api:jar:1.1.0.Final
實現版本:
- org.hibernate:hibernate-validator:5.2.4.Final
- org.apache.bval:bval-jsr303:0.5
- jersery
注解
@NotNull | 引用類型 | 注解元素必須非空
@Null | 引用類型 |元素為空
@Digits | byte,short,int,long及其包裝器,BigDecimal,BigInteger,String| 驗證數字是否合法。屬性:integer(整數部分), fraction(小數部分)
@Future/@Past| java.util.Date, java.util.Calendar | 是否在當前時間之后或之前
@Max/@Min | byte,short,int,long及其包裝器,BigDecimal,BigInteger | 驗證值是否小於等於最大指定整數值或大於等於最小指定整數值
@Pattern | String |驗證字符串是否匹配指定的正則表達式。屬性:regexp(正則), flags(選項,Pattern.Flag值)
@Size | String, Collection, Map, 數組 | 驗證元素大小是否在指定范圍內。屬性:max(最大長度), min(最小長度), message(提示,默認為{constraint.size})
@DecimalMax/@DecimalMin | byte,short,int,long及其包裝器,BigDecimal,BigInteger,String | 驗證值是否小於等於最大指定小數值或大於等於最小指定小數值
@Valid | |驗證值是否需要遞歸調用
@Null
@NotNull
@AssertFalse
@AssertTrue
@DecimalMax(value) 不大於value的數值
@DecimalMin(value) 不小於value的數值
@Digits(integer,fraction) 整數部分不超過integer,小數部分不超過fraction
@Future 將來的日期
@Past 過去的日期
@Max(value) 不大於value的數值
@Min(value) 不小於value的數值
@Pattern(value) 滿足指定正則表達式
@Size(max,min) 長度在min到max之間
定義自己的約束類型
定義注解,message、groups和payload三個屬性是必須定義的。
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MoneyValidator.class) //用於限制的注解,驗證類為MoneyValidator
public @interface Money {
String message() default"不是金額形式";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
定義驗證類
public class MoneyValidator implements ConstraintValidator<Money, Double> {
private String moneyReg = "^\\d+(\\.\\d{1,2})?$";//表示金額的正則表達式
private Pattern moneyPattern = Pattern.compile(moneyReg);
public void initialize(Money money) {
// TODO Auto-generated method stub
}
public boolean isValid(Double value, ConstraintValidatorContext arg1) {
// TODO Auto-generated method stub
if (value == null)
return true;
return moneyPattern.matcher(value.toString()).matches();
}
}
ConstraintValidator使用了泛型,有兩個類型參數。第一個類型是對應的initialize方法的參數類型(約束注解類型),第二個類型是對應的isValid方法的第一個參數類型。
Hibernate Validator
Hibernate Validator附加的constraint(hibernate-validator和validation-api)
@Email 被注釋的元素必須是電子郵箱地址
@Length 字符串的大小必須在指定的范圍內
@NotEmpty 被注釋的字符串的必須非空
@Range 被注釋的元素必須在合適的范圍內
驗證對象類型
字段約束
當約束被定義在字段上的時候, 這個字段的值是通過字段訪問策略來獲取並驗證的. 也就是說Bean Validation的實現者會直接訪問這個實例變量而不會調用屬性的訪問器(getter) 即使這個方法存在。靜態字段或者屬性是不會被校驗的
屬性約束
必須遵守JavaBeans規范,且定義在getter上,不能定義在setter上
類約束
約束繼承
驗證子類時所有基類中的約束也都會被使用
對象圖
@Valid注解類中的對象屬性
Validator接口
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
... = validator.validate(obj); //對一個給定的實體對象中定義的所有約束進行校驗
... = validator.validateProperty(); //通過validateProperty()可以對一個給定實體對象的單個屬性進行校驗,需要符合JavaBean命名規范
... = validator.validateValue(); //校驗如果把一個特定的值賦給一個類的某一個屬性的話,是否會違反此類中定義的約束條件
####約束提示信息
* 可直接通過注解的message屬性設置
* 通過message提供模板,ValidationMessages.properties中定義
Spring MVC Validator接口
--------------------
定義Validator。 Supports方法用於判斷當前的Validator實現類是否支持校驗當前需要校驗的實體類,只有當supports方法的返回結果為true的時候,該Validator接口實現類的validate方法才會被調用來對當前需要校驗的實體類進行校驗。
```java
public class UserValidator implements Validator {
public boolean supports(Class<?> clazz) {
return User.class.equals(clazz);
}
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, "username", null, "Username is empty.");
User user = (User) obj;
if (null == user.getPassword() || "".equals(user.getPassword()))
errors.rejectValue("password", null, "Password is empty.");
}
}
使用Validator進行驗證。在SpringMVC中我們可以使用DataBinder來設定當前Controller需要使用的Validator。
@Controller
public class UserController {
@InitBinder
public void initBinder(DataBinder binder) {
binder.setValidator(new UserValidator());
}
@RequestMapping("login")
public String login(@Valid User user, BindingResult result) {
if (result.hasErrors())
return "redirect:user/login";
return "redirect:/";
}
}
必須使用@Valid標注我們需要校驗的參數user,否則Spring不會對它進行校驗。另外我們的處理器方法必須給定包含Errors的參數,這可以是Errors本身,也可以是它的子類BindingResult,使用了Errors參數就是告訴Spring關於表單對象數據校驗的錯誤將由我們自己來處理,否則Spring會直接拋出異常,而且這個參數是必須緊挨着@Valid參數的,即必須緊挨着需要校驗的參數,這就意味着我們有多少個@Valid參數就需要有多少個對應的Errors參數,它們是一一對應的。
如果我們希望一個Validator對所有的Controller都起作用的話,我們可以通過WebBindingInitializer的initBinder方法來設定了。另外,在SpringMVC的配置文件中通過mvc:annotation-driven的validator屬性也可以指定全局的Validator。
<mvc:annotation-driven validator="userValidator"/>