1. 程式人生 > >struts2中使用xml進行validate驗證

struts2中使用xml進行validate驗證

struts2提供了使用validate框架來實現輸入校驗,這種方式是基於XML的驗證。

檔名為XXXAction-validation.xml

那麼校驗xml檔案格式該如何寫呢?

在此列出此DTD的內容

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
XWork Validators DTD. 
Used the following DOCTYPE. 
<!DOCTYPE validators PUBLIC 
"-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> 
-->
<!ELEMENT validators (field|validator)+>
<!ELEMENT field (field-validator+)> 
<!ATTLIST field 
name CDATA #REQUIRED 
>
<!ELEMENT field-validator (param*, message)> 
<!ATTLIST field-validator 
type CDATA #REQUIRED 
short-circuit (true|false) "false" 
>
<!ELEMENT validator (param*, message)> 
<!ATTLIST validator 
type CDATA #REQUIRED 
short-circuit (true|false) "false" 
>
<!ELEMENT param (#PCDATA)> 
<!ATTLIST param 
name CDATA #REQUIRED 
>
<!ELEMENT message (#PCDATA)> 
<!ATTLIST message 
key CDATA #IMPLIED 
>

由此DTD的定義可知,此XML檔案的根元素為validators。

在根元素下可以有若干個field或validator子元素,即分別代表著欄位校驗和非欄位校驗,它們的區別將在後面介紹。


欄位校驗

欄位校驗代表著field,標籤有個name屬性石必填的,它和表單中的name屬性值是一樣的。
這裡我填入username。

<validators> 
<field name="username"> 
</field> 
</validators>
field下面有個子元素叫field-validator,代表著要用什麼方式來進行校驗,其有個屬性叫 type,也是必填的。
<validators> 
<field name="username"> 
<field-validator type=""> 
</field-validator> 
</field> 
</validators>

type應該填入什麼內容呢?

可以檢視xwork的原始檔,在包 com.opensymphony.xwork2.validator.validators下有個檔案default.xml,在這個檔案中定義了 type屬性值。

<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>

還有很多定義好的type值,這裡不一一列舉

在validator元素中,name屬性表示可以定義的type值,class 表示用哪個類來進行校驗,這是struts2預設設定好的校驗器,我們可以直接使用。

在這個例子中,我們將type設定為requiredstring

<validators> 
<field name="username"> 
<field-validator type="requiredstring"> 
</field-validator> 
</field> 
</validators>

在field-validator下面有兩個子元素,param和message
param可以任意個,可有可無,但是message有且只有一個。

param表示傳入的引數,message表示出錯時顯示的資訊。也就是說message可以是任意的字串,但是param卻是特定的。

在繼續之前還是看看 com.opensymphony.xwork2.validator.validators.RequiredStringValidator這個類的原始碼。首先確定已經下載了原始碼,並且在MyEclipse中關聯了原始碼,這是一個好習慣。

在這個類中有一個成員變數

private boolean doTrim = true;

因此,我們在param中要做的就是,將param元素的name屬性設定為doTrim,值為true。

<validators> 
<field name="username"> 
<field-validator type="requiredstring"> 
<param name="trim"<true>/param> 
<message<username should not be blank!</message> 
</field-validator> 
</field> 
</validators>
trim表示是否忽略空格,預設是true,因此在此也可以省略掉param元素。

其實在 field-validator元素中還有一個屬性short-circuit,其預設值是false,表示的意思是短路,即前面驗證失敗,後面就不做驗證了。

然而這僅僅只是一個校驗條件,還是以 username為例,在上次的例子中,還要求username的長度要在6到10之間,因此,繼續看default.xml檔案

在其中找到這樣一個元素
<validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>

從字面上可以看出是限制字串長度的,因此檢視這個實現類

它有3個成員變數:

private boolean doTrim = true;
private int maxLength = -1;
private int minLength = -1;

其中最主要的是maxLength和minLength分別代表最大長度和最小長度

因此在這個校驗器中內容應該如下:

<field name="username"> 
<field-validator type="stringlength"> 
<param name="minLength">6</param> 
<param name="maxLength">10&lr;/param> 
<message>username should be between ${minLength} and ${maxLength}</message> 
</field-validator> 
</field>

有個問題就是
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>

required和requiredstring有什麼區別嗎?

requiredstring是指這個字串是必須的,而required表示這個欄位是必須的,而沒有指明這個欄位是否必須是字串。

因此對於字串,可以使用requiredstring,而對於非字串型別就必須使用required了。如在這個示例中的age,birthday。注意birthday是Date型別的,不是String。

還是回顧一下register2.jsp的頁面內容。

body中的內容為:
<s:actionerror />
<s:form action="register2" theme="simple">
……
……
</s:form>
但是輸入資料提交後,仍然顯示的是以前的出錯資訊,並不是今天所設定的資訊。

這就涉及到一些知識點了,因為校驗框架產生的錯誤是fielderror,不會在actionerror中顯示。

因此,需要將 theme="simple"去掉,並把那些表格標籤頁去掉,然後執行時會看到在username上方的錯誤資訊。

還有一個問題就是validate校驗框架和Action中validate方法是否衝突。

實際上雖然會使用框架驗證,但是也會呼叫Action的validate方法,通過上面的顯示結果應該可以清楚的看到,在表單上面集中的顯示了actionerror。

但是如果把Action中的validate方法的出錯資訊add到field中會有什麼效果呢??

修改RegisterAction中validate方法,將 addActionError改為addFieldError。

當沒有輸入使用者名稱時,會顯示如下錯誤資訊:

username should not be blank!
username invalid

為什麼會顯示這樣的結果呢???

首先肯定的是在validate中增加的fielderror,和xml中不會衝突

即錯誤資訊不會被覆蓋,而是兩者都有,而且先顯示xml中定義的錯誤資訊,然後才是validate中定義的錯誤資訊。實際上是所有的xml執行完畢後,在執行validate。

為什麼會產生這樣的效果呢???那麼你就必須知道fielderror到底是什麼!繼續檢視原始碼。

因為RegisterAction是繼承的 ActionSupport,addFieldError是繼承自ActionSupport,所以先看看ActionSupport中 addFieldError的實現方法。

在 ActionSupport中addFieldError是這麼實現的,

public void addActionError(String anErrorMessage) {
validationAware.addActionError(anErrorMessage);
}
即通過呼叫validationAware物件的addActionError,而validationAware是 ValidationAwareSupport的一個例項,在ValidationAwareSupport中定義了fielderror是什麼。

private Map>String, List<String>> fieldErrors;
public synchronized void addFieldError(String fieldName, String errorMessage) { 
final Map<String, List<String>> errors = internalGetFieldErrors(); 
List<String> thisFieldErrors = errors.get(fieldName);
if (thisFieldErrors == null) { 
thisFieldErrors = new ArrayList<String>(); 
errors.put(fieldName, thisFieldErrors); 
}
thisFieldErrors.add(errorMessage); 
}

通過原始碼,可以看到fieldErrors實際上是一個Map>String, List<String>>。key是String型別的,而value是List<String>

而實際上這個List是通過ArrayList<String>來實現的,也就是說,key是String型別的,而value是ArrayList<String>。

雖然一個key只能對應一個value,但是在這裡value並不是一個字串,而是一個數組。所以錯誤資訊不會被覆蓋掉。

在ActionSupport類中存在一個方法getFieldErrors,按照方法名可以猜的出該方法返回的是fieldError這個陣列,既然如此那麼是否可以通過 getFieldErrors直接新增呢??

List<String> list = new ArrayList<String>(); 
list.add("username should be between 6 and 10"); 
this.getFieldErrors().put("username",list);

雖然編譯器沒有報錯,但是實際上是不行的。檢視API文件:

getFieldErrors,其解釋如下:

public Map<String,List<String>> getFieldErrors()

Description copied from interface: ValidationAware

Get the field specific errors associated with this action. Error messages should not be added directly here, as implementations are free to return a new Collection or an

Unmodifiable Collection.

註釋:

這個方法返回與這個action相關的具體的fielderrors,錯誤資訊不能直接從這裡新增,執行結果返回一個新的集合或一個不可修改的集合

這是什麼意思呢?看原始碼,這個方法同樣是在 ValidationAwareSupport中實現的。

public synchronized Map<String, List<String>> getFieldErrors() { 
return new LinkedHashMap<String, List<String>>(internalGetFieldErrors()); 
} 
由此可以看到該方法返回的是一個新的LinkedHashMap,只是一個拷貝,而不是原集合,所以這樣直接新增是無法顯示出來的。

那麼何時使用validate驗證框架,什麼時候使用action中的 validate方法呢?

一般來說,簡單驗證可以使用 xml,複雜時用validate

前面講到了 struts2的資料校驗,那麼為什麼要有伺服器校驗??擁有了客戶端校驗不是也行嗎??

服務端校驗是必須的,即使有客戶端校驗。因為可以不通過browser訪問web伺服器!!強健的web應用要有客戶端和伺服器端的驗證。

當然,struts2同樣支援客戶端驗證。

要使用struts2的客戶端校驗,必須滿足一下條件:

1.form的主題(theme)一定不能設定為simple

2.將struts2 form標籤中validate屬性設定為true

但是看到小時效果後就會發現,struts2生成的也是js程式碼,但是效果卻很差,所以一般來說,使用struts2的伺服器端校驗,而客戶端校驗自己寫。

struts2標籤支援事件,可以像使用html標籤一樣使用。

同樣用validate校驗框架也應該可以使用區域性校驗:

當action中有多個方法時,需要在和action同目錄下新建檔案 XXXAction-XXX(方法名)-validation.xml

在例項化子類物件時,會先執行父類的全域性校驗,然後是區域性校驗,接著是子類的全域性校驗,然後是子類的區域性校驗,因此不要提供全域性校驗。

欄位校驗和非欄位校驗的區別

通俗點講:

欄位校驗:校驗誰,用什麼方法

非欄位校驗:用什麼校驗,校驗誰

非欄位校驗示例:

<validator type="requiredstring">
<param name="fieldName">username</param>
<message></message>
</validator>

其中tyoe="fieldName"是不變的。至於其他細節不在這裡詳細敘述。

但還是建議使用欄位校驗器。

下面用一個簡單的例項演示下xml驗證:

本例子實現簡單的登陸輸入驗證:

在myeclipse10下,建立web project,新增struts2.1支援,引入必要的jar包,其中包含commons-validator-xxxx.jar提供validate支援。

首先建立JavaBean:Student.java,位於com.neuq.student包下:

package com.neuq.student;

public class Student {
	private Integer studentid;
	private String password;
	private Integer age;
	public Integer getStudentid() {
		return studentid;
	}
	public void setStudentid(Integer studentid) {
		this.studentid = studentid;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
}

之後建立Action:CheckAction.java,位於com.neuq.check包下:

package com.neuq.check;

import com.neuq.student.Student;
import com.opensymphony.xwork2.ActionSupport;

public class CheckAction extends ActionSupport{
	private Student student;

	public Student getStudent() {
		return student;
	}

	public void setStudent(Student student) {
		this.student = student;
	}

	public String execute() {
			return "toIndex2";
	}
}

之後,在該包(com.neuq.check)下,新增validate檔案CheckAction-validation.xml(注意命名方式),內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>

     <field name="student.studentid">
        <field-validator type="requiredstring">
            <message>request studentid</message>
        </field-validator>
    </field>
    
    <field name="student.password">
        <field-validator type="requiredstring">
            <message>request password</message>
        </field-validator>
    </field>
    
    <field name="student.age">
        <field-validator type="required">
            <message>request age</message>
        </field-validator>
        <field-validator type="int">
            <param name="min">1</param>
            <param name="max">130</param>
            <message>should between ${min} and ${max}</message>
        </field-validator>
    </field>
</validators>

之後修改struts.xml如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
		<action name="aCheck" class="com.neuq.check.CheckAction">
			<result name="toIndex2">/index2.jsp</result>
			<result name="input">/index.jsp</result>
		</action>
	</package>
</struts>    
最後實現前臺jsp設計:

index.jsp:

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<body>
	<s:form action="aCheck">
		<s:textfield name="student.studentid" label="studentid"></s:textfield>
		<s:password name="student.password" label="password"></s:password>
		<s:textfield name="student.age" label="age"></s:textfield>
		<s:submit></s:submit>
	</s:form>
</body>
</html>
index2.jsp:
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<body>
	Validate Success!
</body>
</html>
在tomcat下部署執行,提交資訊,會看到提示資訊。

方法二:

在之前的基礎上,修改CheckAction-validation.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
     <field name="student">
        <field-validator type="visitor">
            <param name="context">student</param>
            <param name="appendPrefix">true</param>
            <message key="appendPrefix">user''s </message>
        </field-validator>
    </field>
</validators>
student指定了action中變數的名字,visitor是固定寫法,student是JavaBean所在包下validate檔名的中間部分。

在com.neuq.student包下建立Student的驗證Student-student-validation.xml,命名方式為“class名+context引數指定的值+validation.xml,內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>

     <field name="studentid">
        <field-validator type="requiredstring">
            <message>request studentid</message>
        </field-validator>
    </field>
    
    <field name="password">
        <field-validator type="requiredstring">
            <message>request password</message>
        </field-validator>
    </field>
    
    <field name="age">
        <field-validator type="required">
            <message>request age</message>
        </field-validator>
        <field-validator type="int">
            <param name="min">1</param>
            <param name="max">130</param>
            <message>should between ${min} and ${max}</message>
        </field-validator>
    </field>
</validators>
注意,studentid,password,age不需要加JavaBean字首。
重新部署執行,成功!
總結:
第一種validation方式,把驗證集中action的驗證檔案中。當驗證的內容少或者不同的action驗證的內容重複性小的時候適用。
第二種validation方式,把驗證集中在bean的驗證檔案中。當多個action都需要對相同bean的內容進行驗證時,比較方便。

相關推薦

struts2使用xml進行validate驗證

struts2提供了使用validate框架來實現輸入校驗,這種方式是基於XML的驗證。 檔名為XXXAction-validation.xml。 那麼校驗xml檔案格式該如何寫呢? 在此列出此DTD的內容 <?xml version="1.0" encodi

實現Struts2對未登入的jsp頁面進行攔截功能(採用的是Struts2過濾器進行過濾攔截)

Struts2中攔截器大家都很經常使用,但是攔截器只能攔截action不能攔截jsp頁面。這個時候就有點尷尬了,按道理來說沒登入的使用者只能看login介面不能夠通過輸入URL進行介面跳轉,這顯然是不合理的。這裡介紹Struts2中Filter實現jsp頁面攔截的功能。(有

使用easyUI的jquery.validate.min.js外掛進行表單驗證並自定義校驗規則

以前使用原生的js或者jQuery寫表單驗證真的好麻煩,使用上面的easyUI外掛配合著ajax真的節省好多程式碼量直接上程式碼<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%&g

jq的表單驗證插件------jquery.validate

此外 郵箱 method 你們 ostc [0 ade 使用 js代碼 今天我們來說一下表單驗證,有人說我們在進行表單驗證的時候使用正則來驗證是非常麻煩的,現在我來給大家介紹一下表單驗證的插件:jquery.validate.min.js 它是與jquery一起結合

Struts2validate數據校驗的兩種常用方法

red 有一種 資源文件 業務 相同 dna erp wrong 顯示 本文主要介紹Struts2中validate數據校驗的兩種方法及Struts2常用校驗器. 1.Action中的validate()方法 Struts2提供了一個Validateable接口,這個接口

圖片驗證碼(Struts2使用)

五個 [] ext.get 圖片 發送請求 pan 畫筆 資源 contex 寫在前面:   最近在項目中做了一個登錄頁面,用到了圖片驗證碼的功能,所以記錄一下。方便之後再有用到,直接拿來用即可。其實圖片驗證碼的生成都是有固定步驟的,網上也有很多的例子,有的時候,如果不想深

5、xamarin.android 如何對AndroidManifest.xml 進行配置和調整

receive custom 5.1 包裝 view 調整 加權 啟動 callable 我們在翻看一些java的源碼經常會說我們要在AndroidManifest.xml 中添加一些東西。而我們使用xamarin裏面實際上是通過C#的特性Attribute進行標記實現的

XML必須進行轉義的字符

寫入 符號 實體 class 進行 好的 大於 引號 都是 XML實體中不允許出現"&","<",">"等特殊字符,否則XML語法檢查時將出錯,如果編寫的XML文件必須包含這些字符,則必須分別寫成"&amp;","&lt;","&

ssm通過ajax或jquer的validate驗證原密碼與修改密碼的正確性

一.ajax 1. <script type="text/javascript"> //驗證原密碼1.ajax,正則 var ok1=false,ok2=false,ok3=false; $(function () { $

第14講 struts2struts.xml的標籤配置

1複製專案,HeadFirstStruts2chapter02_06 改名:HeadFirstStruts2chapter02_07,同時修改web project settings 2修改HelloAction,name屬性,get() set()方法,package com.cruis

關於struts2的攔截器和登陸驗證

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

將資料庫查詢資料封裝到XML檔案進行格式化處理,並進行加密操作,和解密操作

1.pom檔案 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7&l

struts2struts.xml配置檔案詳解

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://st

Struts2的web.xml檔案

<filter> <!-- 配置Struts2核心Filter的名字 --> <filter-name>struts2</filter-name> <!-- 配置Struts2核心F

Struts2編寫struts.xml控制器檔案

<!--struts.xml檔案--> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD

第14講 struts2struts.xml的標籤配置

1複製專案,HeadFirstStruts2chapter02_06 改名:HeadFirstStruts2chapter02_07,同時修改web project settings 2修改HelloAction,name屬性,get() set()方法,package co

Struts2驗證框架的配置及Validation.Xml常用的驗證規則

<field name="username"> <field-validator type="required"> <message>指定檢驗失敗的提示資訊</message> </field-validator> </field> &l

Struts2:對Action方法進行輸入校驗

原始碼下載地址:http://download.csdn.net/detail/zhoujing_0424/9239429 在struts2中,我們可以實現對action的所有方法進行校驗或對action的指定方法進行校驗。對於輸入校驗,struts2提供了兩

Struts2——strtus.xmlmethod配置的幾種方法

strtus.xml中method配置的幾種方法 public class ProductAction extends ActionSupport{public String find(){System.out.println("find");return Action.S

關於idea建立struts2web.xml的filter的urlstruts無法解析的問題

新建完成之後,我們可以看到只有六個基礎包,網上看視訊的時候發現引入的包很多,開始以為是沒有引入相應的包,的確,看報名確實沒有,但是這個相應的包是包含在struts2-core.jar裡面的。不是引入包的問題。那就是路徑問題了。我們看相應的路徑的時候,發現沒有ng這個目錄。 但是在xml中石油這