實作 Validator


使 用SimpleFormController時,您可以搭配一個org.springframework.validation.Validator介面 的實作物件,幫助您作基本的伺服端資料驗證工作,您可以設計一個通用的Validator,將之當作一個Bean注入給需要進行表單驗證的其它Bean物 件。

Validator介面有兩個必須實作的方法,其定義如下所示:
package org.springframework.validation;

public interface Validator {
    boolean supports(Class clazz);
    void validate(Object obj, Errors errors);
}

supports()方法回傳一個boolean值,表示是否支援對所傳入的物件進行驗證,只有在傳回true的情況下,才會使用validate()方 法進行驗證工作,在validate()方法的參數中,obj表示傳入的表單物件,您可以對它進行一些驗證,如果有錯誤的話,可以使用Errors的 reject()或rejectValue()等方法加入錯誤訊息,在後續的處理中,若errors物件中包括錯誤訊息,會回到getViewPage ()所設定的頁面。

來看一個簡單的實作:
package onlyfun.caterpillar;

import org.springframework.validation.Validator;
import org.springframework.validation.Errors;

public class LoginValidator implements Validator {
    public boolean supports(Class clazz) {
        return clazz.equals(LoginForm.class);
    }
   
    public void validate(Object obj, Errors errors) {
        LoginForm form = (LoginForm) obj;
       
        if(form.getPassword().length() < 4 ) {
            errors.rejectValue("password",
                 "less-than-four", null, "密碼不得小於四個字元");
        }
    }
}

這個Validator類別可以搭配7.2.7介紹的SimpleFormDemo專案來使用,驗證通常是在檢查資料的完備性、安全性等條件,像是檢查密碼的格式就是一例,至於使用者名稱與密碼是否正確,這該算是後繼的Controller的處理工作。

搭配SimpleFormController來使用Validator,您只要在Bean定義檔中加入Validator的Bean定義,以及讓SimpleFormController參考到它即可,例如:
...
<bean id="loginValidator"
       class="onlyfun.caterpillar.LoginValidator"/>
  
<bean id="loginAction"
       class="onlyfun.caterpillar.LoginAction">
    <property name="commandClass">
        <value>onlyfun.caterpillar.LoginForm</value>
    </property>
    <property name="validator">
        <ref bean="loginValidator"/>
    </property>
    <property name="successView">
        <value>success</value>
    </property>
    <property name="formView">
        <value>form</value>
    </property>
</bean>
...

"validator"屬性參考至loginValidator實例,只要有設定"validator",SimpleFormController就會使用它。

在進行驗證時,您可以使用org.springframework.validation.ValidationUtils,上面有一些方便的靜態方法, 像是rejectIfEmpty()、rejectIfEmptyOrWhitespace()等,可以查查線上API文件看如何使用。

另一方面,對於AbstractWizardFormController,您可以重新定義它的validatePage()方法來進行驗證,例如:
...
    protected void validatePage(Object command,
                                Errors errors, int page) {
        (YourCommand) your = (YourCommand) command;
        switch(page) {
             case 1:
                  validator.validateSome(your, errors);
                 break;
             case 2:
                  validator.validateOther(your, errors);
                 break;
              ....
        }
    }
..

每進行一頁Wizard表單,都會呼叫該方法一次,讓您針對該次送出的數據進行驗證,"page"參數表示該次送出表單的頁數,與 SimpleFormController的Validator不同的是,AbstractWizardFormController不會自動調用 Validator的validate()方法,您要根據當次頁面的資料自行進行對應的方法驗證,通常採取如上的委託物件,將驗證交由一個 Validator物件來執行。