Java數據校驗(Bean Validation / JSR303)


文檔: 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"/>

Spring可以通過@Resource或@AutoWired注解向ConstraintValidator注入對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM