亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Valang Validator 攻略

系統(tǒng) 1870 0
Valang 是 Validation Language 的縮寫,Valang Validator 的字面含義就是“使用驗證語言的驗證器”,是一種支持聲明的驗證器。本文詳細的介紹了 ValangValidator 的使用和相關(guān)所需的配置。作為一種新型的驗證工具,它提供的驗證語言(valang)具有簡單、易學,易擴展等特點。

Valang 是 Validation Language 的縮寫,Valang Validator 的字面含義就是“使用驗證語言的驗證器”,它是一種支持聲明的驗證器。作為新出的驗證工具,它擁有不同于現(xiàn)有其它相似工具的特點:

  • 基于聲明的驗證工具包,大多數(shù)情況下可以避免手工書寫代碼。
  • 提供了一套精巧的 DSL(Domain Specific language),支持表達式語言。語法非常簡潔,且支持擴展方便。
  • 配置精簡,可讀性高、易維護。
  • 包含在 Spring Module 中,簡化了 Spring Framework 的 Validator 使用。
  • 支持 JavaScript,對于 Web 應(yīng)用,支持客戶端的驗證。

本文將帶領(lǐng)讀者對以上特點一一尋訪,在進一步閱讀本文之前,請確保讀者具有 Spring Framework 的使用經(jīng)驗,如果有 Spring MVC 的經(jīng)驗更佳。

使用概覽

Valang Validator 屬于 Spring Module 的 Validation 模塊。Spring Module 是一組擴展 Spring Framework 功能的工具集,當前的版本是 0.6。它作為獨立于 Spring Framework 的項目而存在,其目的非常單純:方便 Spring Framework 與其它框架的集成,避免為此修改 Spring Framework 的核心。

使用 Valang Validator 必須先了解它的兩個重要組件:

  • valang,即驗證語法,使用者使用它將約束定義轉(zhuǎn)化為 ValangValidator 能解析的驗證規(guī)則。
  • ValangValidator,它是 Spring Validator 接口的具體實現(xiàn)。負責驗證規(guī)則解析,完成實際的驗證工作。

了解了這些關(guān)于 Valang Validator 的信息之后,不妨從一個例子來了解它的使用。本例使用的環(huán)境:JDK 1.5、Spring Framework2.0 和 Spring Module 0.6。

問題描述

為 了盡可能的體現(xiàn) Valang Validator 的特點,例子中需要驗證的對象有意地被設(shè)計得稍微有些復(fù)雜:首先,屬性是最常見的 3 種類型,而且其中還有一個是在 Java 中有些煩人的Date;其次,它還包含了一個成員類屬性。關(guān)于類結(jié)構(gòu)和相關(guān)的約束如下表:

類結(jié)構(gòu) 約束
public class User { private String name; private int age; private Date birthday; private Address address; …… } public class Address { private String state; private String town; private String street; …… } name,必填,且長度不超過 50。
? age,非必填,必須大于等于 0,小于等于 60。
? birthday,非必填,必須在 2000-01-01 之后。
? address.state,必填,長度不超過 50。
? address.town,必填,長度不超過 50。
? address.street,必填,長度不超過 200。

?

實現(xiàn) Validator

實 現(xiàn) Valang Validator 就是要完成兩部分工作:定義 valang 描述和 Validator 創(chuàng)建。Validator 的創(chuàng)建可以使用 Java 代碼進行,也可使用 Spring DI 完成。本例采用后一種方法,Bean 定義如下(文件名:valang.xml):

            <bean id="userValidator" class="org.springmodules.validation.valang.ValangValidator">
	<property name="valang">
		<value>
			<![CDATA[
				{ name  : ? is not null and ? has text and length(?)<= 50 
: 'Name is empty or too long.'}
				{ age : ? between 0 and 60 : 'Age should between 0 and 60.'}

            
              |-------10--------20--------30--------40--------50--------60--------70--------80--------9|
            
            
              |-------- XML error:  The previous line is longer than the max of 90 characters ---------|
            
            

				{ birthday : ? is null or ? >[20000101]
 : 'Birthday should be after 2000-01-01.'}
                { address : ? is not null : 'Address is empty.'}
				{ address.state : address is null or ( ? is not null and
                                 ? has text and length(?)<=50 )
: 'state is empty or too long.'}
                { address.town : address is null or ( ? is not null and  
? has text and length(?)<=50 )
: 'town is empty or too long.'}
                { address.street : address is null or ( ? is not null and
 ? has text and length(?)<=50 )
: 'street is empty or too long.'}	
	    ]]>
		</value>
	</property>
	<property name="dateParsers">
		<map>
			<entry key="^\\d{8}$" value="yyyyMMdd" />
		</map>
	</property>
</bean>

          

?

瞧,沒有一行 Java 代碼,居然完成了一個 Validator 的定義。這其中的秘密就是 valang 屬性,它定義了驗證規(guī)則。再看看它的語法,是不是很酷?!另一個屬性 dateParsers 定義了日期轉(zhuǎn)換的格式。關(guān)于它們的解釋在后面有詳細的介紹。

技巧:

如 果 Adress 對象被多個對象引用,且對于 Address 的驗證約束相同,那么以上的 address 相關(guān)的約束規(guī)則就需要重復(fù)書寫。這樣,既繁且不利于維護。此時,可以將 address 相關(guān)的約束組織成一個 validator,實現(xiàn)約束的復(fù)用。具體步驟:

a) 抽取 Address 的約束到 addressValidator。

            <bean id="addressValidator" class="org.springmodules.validation.valang.ValangValidator">
	<property name="valang">
		<value>
			<![CDATA[
			{ state : ? is not null and  ? has text and length(?)<=50
 : 'state is empty or too long.'}
            { town : ? is not null and  ? has text and length(?)<=50
 : 'town is empty or too long.'}
            { street : ? is not null and  ? has text and length(?)<=50
 : 'street is empty or too long.'}
			]]>			
		</value>
	</property>
</bean>

          

?

b) 實現(xiàn)繼承 ValangValidator 的 UserValidator,包含 addressValidator:

            public class UserValidator extends ValangValidator {
private Validator addressValidator;

    public void setAddressValidator(Validator addressValidator) {
        this.addressValidator = addressValidator;
    }
    
    public void validate(Object target, Errors errors){
        super.validate( target, errors);
        Address address= ((User)target).getAddress();
        // address 為 null 時,不進行進一步的驗證。
        if( null!= address){
            //注意與 popNestedPath 成對使用
            errors.pushNestedPath("address");
            //驗證 address
            addressValidator.validate( address, errors);
            errors.popNestedPath();
        }
    }
}

          

?

c) 修改 userValidator 的配置。

            <bean id="userValidator" class="包名.UserValidator">
    <property name="addressValidator" ref="addressValidator"/>
	<property name="valang">
		<value>
			<![CDATA[
			{ name : ? is not null and ? has text and length(?)<= 50
: 'Name is empty or too long.'}
			{ age : ? between 0 and 60 : 'Age should between 0 and 60.'}
			{ birthday : ? is null or ? >[20000101] : 'Birthday should be after 2000-01-01.'}

            
              |-------10--------20--------30--------40--------50--------60--------70--------80--------9|
            
            
              |-------- XML error:  The previous line is longer than the max of 90 characters ---------|
            
            

            { address : ? is not null : 'Address is empty.'}
			]]>			
		</value>
	</property>
	<property name="dateParsers">
		<map>
			<entry key="^\\d{8}$" value="yyyyMMdd" />
		</map>
	</property>
</bean>

          

?

單元測試

對 ValangValidator 進行單元測試非常簡單,需要注意的是它的實例化。這里使用 BeanFactory 來創(chuàng)建待測的 Validator。Spring 提供了測試用例基類 AbstractDependencyInjectionSpringContextTests,使得手工創(chuàng)建完全避免:

            public class UserValidatorTest extends AbstractDependencyInjectionSpringContextTests {
    private Validator userValidator;
    
    public UserValidatorTest(){
        super();
        //缺省是AUTOWIRE_BY_TYPE,當Bean文件有2個以上的同類型
        //Bean定義時就應(yīng)該采用AUTOWIRE_BY_NAME方式。
        setAutowireMode(AUTOWIRE_BY_NAME);
    }

protected String[] getConfigLocations() {
    //指明配置文件的位置
        return new String[]{"file:文件路徑/valang.xml"};
    }
    //基類調(diào)用該方法完成依賴注入(DI)
    public void setUserValidator(Validator userValidator) {
        this.userValidator = userValidator;
    }
    
    public void testEmptyObject(){
        User user= new User();
        BindException errors= new BindException(user, "target");
        userValidator.validate( user, errors);
        assertTrue( errors.getAllErrors().size()== 2);
        ObjectError error1= (ObjectError)(errors.getAllErrors().get(0));
        assertEquals(error1.getDefaultMessage(), "Name is empty or too long.");
        ObjectError error2= (ObjectError)(errors.getAllErrors().get(1));
        assertEquals(error2.getDefaultMessage(), "Address is empty.");
}
……
}

          

?

使用 Validator

上面的單元測試已經(jīng)展示了 ValangValidator 的使用,除此之外,也可使用 BeanFactory 將它注入某個控制器中使用:

            <bean id="userController" class="……">
    ……
	<property name="validator" ref="userValidator"/>
</bean>

          

?

從上面的例子來看,ValangValidator 的使用相當簡單。尤其對于有過 Spring 經(jīng)驗的用戶來說,除了需要掌握 valang 語法之外,其余的根本就和 Spring Validator 使用一樣。而且,例子中 valang 的語法所展示的簡潔、直觀給人留下了深刻的印象。

?




回頁首


Valang 語法

很 酷!這是我看到 valang 的第一印象。Spring 數(shù)據(jù)綁定語法相同的屬性表達式,靈活、便捷、易學的語法。這些,都使得另一個被廣泛使用的聲明性驗證工具 Commons Validator 顯得相形見絀。雖然作為早期的聲明性驗證工具的實現(xiàn),Commons Validator 的功績不可磨滅,但是其配置的繁瑣也使人厭煩不已。

“以數(shù)據(jù)為中心”是 ValangValidator 的設(shè)計思路,此處的數(shù)據(jù)就是 valang 描述。valang 由一系列的規(guī)則組成,對于每個規(guī)則,它的結(jié)構(gòu)如下:

            { <key> : <predicate_expression> : <message> [: <error_code> [: <args> ]] }
          

?

其中:

  • <key>,屬性表達式。它是要驗證的屬性名,必填。
  • <predicate_expression>,謂詞表達式。期望滿足的條件,必填。
  • <message>,缺省消息。當不滿足預(yù)期表達式時顯示的消息,必填。
  • <error_code>,錯誤碼。國際化時使用的消息鍵值,當它存在時缺省消息被忽略,可選。
  • <args>,參數(shù)。逗號分隔的參數(shù)值,用于替換錯誤碼中定義的站位符,可選。

這些參數(shù),除了謂詞表達式之外,都可以在 Spring 中見到它們的蹤影。而它們的含義、用法也絲毫沒有發(fā)生變化。因此,讓我們把關(guān)注的焦點集中在謂詞表達式上。

表達式語法

valang 將謂詞表達式定義成如下結(jié)構(gòu):

            <expression> ::= <expression> ( ( "AND" | "OR" ) <expression> )+ | <predicate>
          

?

其中的謂詞(<predicate>),是由操作符、文字常量、bean 屬性、數(shù)學表達式和函數(shù)組成的可計算實體。

1.操作符

valang 的操作符有三種:一元操作符,二元操作符和其他操作符。支持的操作符如下表:

類型 支持類型 操作符 說明
一元 對象 NULL | IS NULL 為空
NOT NULL | IS NOT NULL 非空
字符串 HAS TEXT 包含非空格的字符
HAS NO TEXT null或只有空格字符
HAS LENGTH | IS NOT BLANK 長度>0
HAS NO LENGTH | IS BLANK null或長度=0
IS UPPERCASE | IS UPPER CASE |
IS UPPER
所有字母大寫
IS NOT UPPERCASE |
IS NOT UPPER CASE |
IS NOT UPPER
不是所有字母大寫
IS LOWERCASE | IS LOWER CASE | IS LOWER 所有字母小寫
IS NOT LOWERCASE |
IS NOT LOWER CASE |
IS NOT LOWER
不是所有字母小寫
IS WORD
IS NOT WORD
二元 字符串、日期、布爾和數(shù)字 = | == | IS | EQUALS 相等
!= | <> | >< | IS NOT | NOT EQUALS 不等
數(shù)字、日期 >|GREATER THAN |
IS GREATER THAN
大于
< | LESS THAN | IS LESS THAN 小于
>= | => |
GREATER THAN OR EQUALS |
IS GREATER THAN OR EQUALS
大于等于
<= | =< | LESS THAN OR EQUALS | IS LESS THAN OR EQUALS 小于等于
其他 數(shù)字、日期 BETWEEN A AND B 大于等于A,且小于等于B
NOT BETWEEN A AND B 小于A,或大于B
字符串、日期、布爾和數(shù)字 IN <value> (, <value>)* 在值列表中
NOT IN <value> (, <value>)* 不在值列表中
布爾表達式 NOT 取反

這些操作符是大小寫非敏感的,另外在使用時需要注意:

  • 避免在驗證時出現(xiàn) NullException,這一點可以在 userValidator 的例子中看到。
  • 二元操作符兩邊的操作數(shù)類型必須一致。

?

2.文字常數(shù)

Valang 支持 4 種文字常數(shù):字符串、數(shù)字、日期和布爾。這四種類型的文字常數(shù)如下表:

類型 說明
字符串 字符串使用單引號包含,如 ’foxgem’。
數(shù)字 數(shù)字被轉(zhuǎn)換為 java.math.BigDecimal。
布爾 布爾值必須是:TRUE、YES、FALSE、NO 中的一個,且不要使用單引號。
日期 日期值使用 [] 包含,如 [2000-01-01]。

valang 對于日期類型的處理非常特殊,而且有趣:

  • 使用 T 來代表當前時間, 如 [T]。
  • 提供了移位操作,語法是:日期 > 時間單位,日期 < 時間單位。前者表示將日期中對應(yīng)的單位部分向后滾動到該時間單位的最大值;后者表示將日期中對應(yīng)的單位部分向前滾動到該時間單位的最小值。支持的時間單位和對應(yīng)范圍:

    1) 秒(s):0~999 毫秒
    2) 分鐘(m):0秒0毫秒 ~ 59秒999毫秒
    3) 小時(H):0分0秒0毫秒 ~ 59分59秒999毫秒
    4) 天(d):0時0分0秒0毫秒 ~ 23時59分59秒999毫秒
    5) 星期(w):周一0時0分0秒0毫秒 ~ 周日23時59分59秒999毫秒
    6) 月(M):月第一天0時0分0秒0毫秒 ~ 月最后一天23時59分59秒999毫秒
    7) 年(y):年第一天0時0分0秒0毫秒 ~ 年最后一天23時59分59秒999毫秒

    如:[T>d],表示當天的 23 時 59 分 59 秒 999 毫秒。

  • 支持日期的增減運算。增減分別對應(yīng):“+”和“-”;數(shù)量對應(yīng):i 時間單位,i 表示整數(shù)。如:[T>d-1d+2H],表示先將當前時間后滾至當天的最后時刻,再減去一天,再加上 2 個小時。

    日期格式在 valang 中也有很好的支持,可以很方便的定義自己的格式。日期解析過程如下:

    1) 取出日期字符串,在 dateParsers 中定義 Map 的正則表達式鍵集合中進行匹配。
    2) 當找到符合的正則表達式時,以它為鍵值獲取對應(yīng)的日期格式串。
    3) 使用 SimpleDateFomat,將日期字符串按照日期格式串轉(zhuǎn)化為對應(yīng)的 Date 類型。

    因此,如果要在 valang 中使用 yyyy-MM-dd 的格式時,那么使用以下的定義:

                    <entry key="^\\d{4}-\\d{2}-\\d{2}$" value="yyyy-MM-dd" />
    
                  

3. bean 屬性

bean 屬性的用法和屬性表達式的用法一樣,在運行時它的值會被取出。另外,valang 使用“?”來表示在規(guī)則中定義的屬性表達式的值。

4. 數(shù)學表達式

valang 支持的數(shù)學運算符有:+、-、*、/(或 div)、%(或 mod)。

5.函數(shù)

valang 內(nèi)置的函數(shù)如下:

函數(shù) 說明
length | len | size |count 如果傳入?yún)?shù)是集合或數(shù)組,那么返回它們的大小;否則,返回傳入?yún)?shù)的 toString 所返回字符串的長度。
使用例子:length(?)<50
match | matches 傳入?yún)?shù)(參數(shù) 2)的 toString 返回的字符串是否匹配給定的正則表達式(參數(shù)1)。
使用例子:match('^\\d{2}$', ?) is true
email 傳入?yún)?shù)的 toString 返回的字符串是有效的 email。
使用例子:email(?) is true
upper 將傳入?yún)?shù)的 toString 返回的字符串轉(zhuǎn)換為大寫。
使用例子:upper(?)=='VALANG'
lower 將傳入?yún)?shù)的 toString 返回的字符串轉(zhuǎn)換為小寫。
使用例子:lower(?)=='valang'
! 布爾值取反
使用例子:!(?) is true。

注意:它不能內(nèi)嵌表達式,如“!(length(?)<= 50) is true”將會出錯。
resolve 解析消息碼。
inRole 傳入?yún)?shù)是角色名,如果當前用戶有這個角色,則返回 true。

valang 對于函數(shù)的支持并不是只僅僅提供幾個簡單的函數(shù),它還允許用戶自定義函數(shù)。這大大的擴展了它的表現(xiàn)力。

?




回頁首


自定義函數(shù)

org.springmodules.validation.valang.functions.AbstractFunction 是 valang 函數(shù)的基類,所有的內(nèi)置函數(shù)都是它的子類,自定義函數(shù)也必須從它繼承。AbstractFunction 有幾個重要的方法需要注意:

  • 構(gòu)造函數(shù),子類必須實現(xiàn),不要忘了先調(diào)用 super。
  • definedExactNumberOfArguments、 definedMaxNumberOfArguments、definedMinNumberOfArguments,分別是定義函數(shù)的參數(shù)個數(shù),函數(shù)的 最大參數(shù)個數(shù)、函數(shù)的最小參數(shù)個數(shù)。它們在構(gòu)造函數(shù)中被調(diào)用。
  • init,在所有屬性被設(shè)置后調(diào)用,負責初始化。
  • isAutowireByName 和 isAutowireByType,分別指定了函數(shù)的屬性被 BeanFactory 自動裝配采用的方法。
  • doGetResult,返回函數(shù)的結(jié)果。

下面通過實現(xiàn)一個自定義版本的 length 函數(shù)來了解自定義函數(shù)的編寫和配置:

函數(shù)定義:

            public class AnotherLengthFunction extends AbstractFunction {

    public AnotherLengthFunction(Function[] functions, int line, int column) {
        super(functions, line, column);
        //AnotherLengthFunction只支持一個參數(shù)
        definedExactNumberOfArguments(1);
    }

protected Object doGetResult(Object target) throws Exception {
    //返回參數(shù)1的toString的值。如果有多個參數(shù),那么:
    //參數(shù)2:getArguments()[1].getResult(target).toString();以此類推。
//另外getArguments()的個數(shù)就是實際傳入的參數(shù)個數(shù)。
        String value= getArguments()[0].getResult(target).toString();
        return new Integer(value.length());
    }

}

          

?

函數(shù)配置:

            <property name="customFunctions">
	<map>
        <!-- 前者是函數(shù)使用的名字,后者對應(yīng)函數(shù)實現(xiàn)的class。
            使用例子:anotherLength(?)<50
-->
		<entry key="anotherLength" value="AnotherLengthFunction"/>
	</map>
</property>

          

?

當自定義的函數(shù)需要外部的資源,如數(shù)據(jù)庫連接、網(wǎng)絡(luò)連接、文件等,可以通過 BeanFactory 自動裝配來完成。此時需要覆蓋 isAutowireByName 或 isAutowireByType,指定自動裝配的類型,這兩個函數(shù)不能同時覆蓋。

?




回頁首


客戶端驗證

對于 Web 應(yīng)用程序來說,服務(wù)器的驗證固然是必須的,但如果提供了客戶端驗證的話,那無疑是錦上添花的事情。幸運的是,Valang Validator 已經(jīng)做到了這一點。要使用這一功能,需要先了解 2 個組件:

1. org.springmodules.validation.valang.javascript.taglib.ValangRulesExportInterceptor

這個攔截器的作用是輸出被當前請求處理器所使用的 valang 驗證規(guī)則到 ModelAndView 中,使 <validate> 可以利用這些信息。

在以下情況下之一時,該攔截器不做任何事情:

  • 當被攔截的請求處理器不是 BaseCommandController。
  • 請求處理器使用的 Validator 不是 ValangValidator 實例。
  • 請求處理器不輸出一個 Command 對象到 model 中。

2. valang 標簽庫

valang 標簽庫完成客戶端腳本的產(chǎn)生,并進行實際的客戶端驗證。它包含了 2 個標簽:

標簽 作用 屬性 說明
codebase 產(chǎn)生被翻譯的 javascript 驗證規(guī)則執(zhí)行所需要的代碼。它應(yīng)該每頁包含一次,且在被產(chǎn)生的驗證規(guī)則之前。 includeScriptTags 非必須,指示產(chǎn)生的 javascript 代碼是否被 <script> 包含。
fieldErrorsIdSuffix 非必須,指明用來包含屬性錯誤信息的 <div> 或 <span> 的 id 的后綴。整個 id 的最后組成:
<屬性名 >< fieldErrorsIdSuffix >
globalErrorsId 非必須,指明用來包含全局錯誤信息的 <div> 或 <span> 的 id。
validate 將valang規(guī)則翻譯成對應(yīng)的 javascript 驗證規(guī)則。 commandName 非必須,指明需要驗證的 command 對象名字。

接下來我們以一個例子來展示如何應(yīng)用以上所學。例子本身并不復(fù)雜,就是在以上的 userValidator 例子的基礎(chǔ)上,完成一個 Controller 和相關(guān)的 JSP 頁面。例子的步驟和說明如下:

1. Controller 負責初始化 User 對象,在提交時取出 User 各屬性的值放入到 ModelAndView 中。

            public class UserController extends SimpleFormController {
    
    protected Object formBackingObject(HttpServletRequest request){
        User user= new User();
        user.setAddress( new Address());
        return user;
    }
    
    protected ModelAndView onSubmit(Object command) throws Exception{
        User user=(User)command;
        ModelAndView mav= new ModelAndView(getSuccessView());
        //取出user的屬性,放到mav中。
        mav.addObject("isSubmit", "true");//提交處理的標志。
        return mav;
    }
    
    protected void initBinder(HttpServletRequest request,
                              ServletRequestDataBinder binder)
                              throws Exception{
        SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
        binder.registerCustomEditor(Date.class, "birthday"
                                  , new CustomDateEditor(format, true));
    }
}

          

?

2. JSP 頁面既充當 User 的編輯頁面,又是 Controller 提交后的屬性顯示頁面。它演示了 valang 標簽庫的配置和使用,是本例的重頭戲。本例中使用了 Spring 2.0 中提供的 Spring Form 標簽,關(guān)于它的使用請參見 Spring 手冊。

            <%@ page contentType="text/html" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!-- 包含valang標簽庫 -->
<%@ taglib prefix="valang" uri="http://www.springmodules.org/tags/valang" %>
   
<html>
  <head>
<title>User Detail</title>
<!-- 請將codebase包含在<head>中,確保在頁面顯示時,
所需要的環(huán)境已經(jīng)產(chǎn)生 -->
    <valang:codebase includeScriptTags="true" fieldErrorsIdSuffix="_error" 
                     globalErrorsId="global_error"/>
  </head>

  <body>
    <c:if test="${not empty param.isSubmit}">
      <!-- 顯示提交之后的User各屬性值 -->
    </c:if>
    <c:if test="${empty param.isSubmit}">
<form:form commandName="user" method="post">
  <!-- validate需要包含在<form>中,commandName
是UserController的CommandName -->
      <valang:validate commandName="user"/>
      <div id="global_error">
      </div>
      <table>
      	<tr>
      	  <td>name:</td>
      	  <td>
      		<form:input path="name" />
            <!-- 注意id的命名。在_error之前的屬性名實際是
在valang驗證規(guī)則中出現(xiàn)的屬性表達式的名字。否則,將出錯。
如:以上的userValidator的例子中,如果將address相關(guān)的屬性
合并到一個中:
{ address: ? is not null 
	        and address.state is not null and length(address.state)<= 50
and address.town is not null and length(address.town)<= 50
	        and address.street is not null and length(address.street)<= 50
	       : 'Invalida address.'}
那么,下面的 address 相關(guān)的屬性對應(yīng)的 <span> 的 id 就應(yīng)該是:
address_error,且只有一個。因為多個時,會引起 javascript 的錯誤。
 -->
      		<span id="name_error"><form:errors path="name"/></span>
      	  </td>
      	</tr>
      	<tr>
      	  <td>age:</td>
      	  <td>
      		<form:input path="age" />
      		<span id="age_error"><form:errors path="age" /></span>
      	  </td>
      	</tr>
      	<tr>
      	  <td>birthday:</td>
      	  <td>
      		<form:input path="birthday" />
      		<span id="birthday_error"><form:errors path="birthday" /></span>
      	  </td>
      	</tr>
      	<tr>
      	  <td>state:</td>
      	  <td>
      		<form:input path="address.state" />
      		<span id="address.state_error"><form:errors path="address.state" /></span>
      	  </td>
      	</tr>
      	<tr>
      	  <td>town:</td>
      	  <td>
      		<form:input path="address.town" />
      		<span id="address.town_error"><form:errors path="address.town" /></span>
      	  </td>
      	</tr>
      	<tr>
      	  <td>street:</td>
      	  <td>
      		<form:input path="address.street" />
      		<span id="address.street_error"><form:errors path="address.street" /></span>

            
              |-------10--------20--------30--------40--------50--------60--------70--------80--------9|
            
            
              |-------- XML error:  The previous line is longer than the max of 90 characters ---------|
            
            

      	  </td>
      	</tr>
      	<tr>
      	  <td colspan="2">
      		<input type="submit" value="Submit" />
      	  </td>
      	</tr>
      </table>
    </form:form>
    </c:if>
  </body>
</html>

          

?

3. 相關(guān)配置。

            <bean id="handlerMapping" 
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="interceptors">
		<list>
			<ref bean="valangInterceptor"/>
		</list>
	</property>
	<property name="urlMap">
		<map>
			<entry key="/userDetail.htm"><ref bean="userController"/></entry>
		</map>
	</property>
</bean>

<bean id="userController" name="/userDetail.htm" class="example.UserController">
	<property name="formView" value="userDetail"/>
	<property name="successView" value="redirect:/userDetail.htm"/>
	<property name="validator" ref="userValidator"/>
    <property name="commandName" value="user"/>
    <property name="commandClass" value="example.User"/>
</bean>

<bean id="valangInterceptor"
 class="org.springmodules.validation.valang.javascript.taglib.ValangRulesExportInterceptor"/>

            
              |-------10--------20--------30--------40--------50--------60--------70--------80--------9|
            
            
              |-------- XML error:  The previous line is longer than the max of 90 characters ---------|
            
            


<bean id="viewResolver"
 class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
</bean>

          





回頁首


結(jié)束語

本 文詳細的介紹了 ValangValidator 的使用和相關(guān)所需的配置。作為一種新型的驗證工具,它提供的驗證語言(valang)具有簡單、易學,易擴展等特點。由于采用驗證語言,在大多數(shù)的情形 下,避免了書寫 Java 驗證代碼的需要。這些特性,極大的簡化了通常繁瑣的驗證實現(xiàn)。與 Spring Framework 結(jié)合,也對于它的推廣有了很好的起點。同時,在使用時也需注意,由于目前它的 1.0 版本尚未正式的發(fā)布,API 尚不穩(wěn)定。對于這一點,使用者也需有心理準備。


參考資料

Valang Validator 攻略


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久精品呦女 | 久青草青综合在线视频 | a成人在线 | 国产一区二区三区影院 | 大陆一级毛片免费视频观看 | 四虎影视免费永久在线观看黄 | 久久婷婷综合中文字幕 | 奇米影视首页 | 国产精品乱码在线观看 | 天天摸天天碰色综合网 | 五月天婷婷在线免费观看 | 成人午夜啪啪免费网站 | 亚洲福利视频一区二区三区 | 色综合综合在线 | 人人狠狠综合久久亚洲88 | 51精品视频在线一区二区 | 亚洲国产精品成人午夜在线观看 | 久草在线最新 | 黄色在线视频网站 | 秘密影院久久综合亚洲综合 | 欧美一区二区精品 | 毛片网络| 亚洲国产大片 | 五月婷婷之综合激情 | 中文字幕一区日韩在线视频 | 91成年人| 九九九九精品视频在线播放 | 亚洲欧美日韩在线观看你懂的 | 天天狠狠操 | 2级毛片 | 日本吻胸抓胸激烈视频网站 | 天天操操操| 白蛇缘起3免费观看 | 日韩在线 中文字幕 | 亚洲欧美另类久久久精品能播放的 | 国产成人亚洲欧美三区综合 | 亚洲精品第一区二区三区 | 亚洲视频免 | 九9热这里只有真品 | 91在线九色| 久草精品视频 |