Struts2的輸入校驗(yàn)和類型轉(zhuǎn)換都是對(duì)請(qǐng)求參數(shù)進(jìn)行處理。
輸入校驗(yàn)顧名思義就是請(qǐng)求參數(shù)是否能夠滿足一定的要求;
客戶端校驗(yàn)是指在瀏覽器這端通過(guò)JavaScript進(jìn)行初步校驗(yàn),為了減輕服務(wù)器端的負(fù)載;
服務(wù)器端校驗(yàn)是校驗(yàn)數(shù)據(jù)的最后一道防線;
只需要一個(gè)配置文件,對(duì)相應(yīng)的校驗(yàn)規(guī)則進(jìn)行配置,即可使用struts2自帶的校驗(yàn)器
自行在action中進(jìn)行自定義的校驗(yàn)則不需要配置規(guī)則文件
一、使用struts2自帶的校驗(yàn)器
1.數(shù)據(jù)校驗(yàn)規(guī)則文件規(guī)則:
1.此文件中規(guī)定了參數(shù)的一些校驗(yàn)條件;
2.可以包括字段型校驗(yàn)器和非字段型校驗(yàn)器;
3.命名規(guī)則:ActionName-validation.xml,其中ActionName是Action類的名字;
4.每個(gè)Action都有一個(gè)validation文件,規(guī)則文件放在和Action同目錄下;
5.在前面我們講到的配置邏輯action中,如果需要對(duì)某個(gè)邏輯Action配置數(shù)據(jù)校驗(yàn)文件,則命名規(guī)則為:ActionName-LogicActionName-validation.xml;
6.注意:當(dāng)需要對(duì)邏輯action進(jìn)行校驗(yàn)時(shí),如果存在一般形式的ActionName-validaton.xml文件,則也會(huì)對(duì)此邏輯Action進(jìn)行校驗(yàn);
7.輸入校驗(yàn)失敗后,和類型轉(zhuǎn)換一樣,會(huì)將錯(cuò)誤封裝成fieldError,并放入Action Context中,因此在JSP中添加<s:fielderror/>可顯示錯(cuò)誤,此內(nèi)容也是我們?cè)跀?shù)據(jù)校驗(yàn)文件中配置的;
8.當(dāng)輸入校驗(yàn)失敗后,和類型轉(zhuǎn)換一樣,返回邏輯視圖為input,因此在struts.xml中必須配<result name="input"></input>
9.輸入校驗(yàn)失敗后,struts表單標(biāo)簽也會(huì)自動(dòng)輸出錯(cuò)誤提示;
字段型校驗(yàn)器&非字段型校驗(yàn)器
字段型校驗(yàn)器:以每個(gè)Action屬性為一個(gè)單位進(jìn)行編寫,即以如下風(fēng)格編寫:
屬性1
規(guī)則1
規(guī)則2
屬性2
規(guī)則1
規(guī)則2
(1)<field name="">為一個(gè)屬性,name為Action屬性名稱;
(2)<field-validator type="">為配置一個(gè)校驗(yàn)器,type為校驗(yàn)器的類型;
(3)<param>為配置參數(shù),比如最小值、最大值;
(4)<message>為錯(cuò)誤信息,如果需要對(duì)錯(cuò)誤提示信息進(jìn)行國(guó)際化,則可以在全局國(guó)際化資源文件中配置,在校驗(yàn)規(guī)則文件中編寫如下形式:<message key="key"/>,key為國(guó)際化資源文件的key即可;
非字段型校驗(yàn)器:以規(guī)則為一個(gè)單位,以如下風(fēng)格編寫:
規(guī)則1
屬性
規(guī)則2
屬性
規(guī)則3
屬性
(1)<validator type="">表示一個(gè)校驗(yàn)器,type屬性表示校驗(yàn)器的類型;
(2)<param name="fieldName"></param> 此元素是必要的,指定Action屬性的名稱;
(3)<message>表示錯(cuò)誤信息;
2.數(shù)據(jù)校驗(yàn)文件內(nèi)容
數(shù)據(jù)校驗(yàn)文件以<validators>為根元素;
字段型校驗(yàn)器是以屬性為單位的,內(nèi)容模板:
<validators>
<field name="">
<field-validator type="">
<param name=""></param>
<message></message>
</field-validator>
</field>
</validators>
非字段型校驗(yàn)器是以校驗(yàn)器為單位的,內(nèi)容模板:
<validator type="">
<param name="fieldName"></param>
<param name=""></param>
<message></message>
</validator>
3、示例:
輸入頁(yè)面:
<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
Created by IntelliJ IDEA.
User: yangcs
Date: 2017/2/8
Time: 14:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>參數(shù)校驗(yàn)</title>
</head>
<body>
<s:form action="Action011">
<s:textfield label="姓名(String,示例:傻逼)" name="name"></s:textfield>
<s:textfield label="年齡(int,示例:23)" name="age"></s:textfield>
<s:textfield label="日期(Date, 示例:2017-02-02)" name="date"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
<s:fielderror></s:fielderror>
</body>
</html>
數(shù)據(jù)處理action:
package test002;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
/**
* Created by yangcs on 2017/2/8.
* 這個(gè)action用于struts2校驗(yàn)器示例
*/
public class Validation01Action extends ActionSupport{
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private int age;
private Date date;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String execute() throws Exception{
return SUCCESS;
}
}
action配置:
<action name="Action011" class="test002.Validation01Action">
<result name="success">/JSP/validationResult.jsp</result>
<result name="input">/JSP/validationError.jsp</result>
</action>
校驗(yàn)規(guī)則文件Validate01Action-validation.xml:
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<!--字段類型的校驗(yàn)配置-->
<validators>
<field name="name">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>姓名不能為空</message>
</field-validator>
<field-validator type="regex">
<param name="trimExpression"><![CDATA[(\w{4,10})]]></param>
<message>姓名要在4-10位之間</message>
</field-validator>
</field>
<field name="age">
<field-validator type="required">
<message>年齡不能為空</message>
</field-validator>
<field-validator type="int">
<param name="min">1</param>
<param name="max">100</param>
<message>年齡限制1到100</message>
</field-validator>
</field>
<field name="date">
<field-validator type="required">
<message>日期不能為空</message>
</field-validator>
<field-validator type="date">
<param name="min">2017-01-01</param>
<param name="max">2017-12-31</param>
<message>日期在2017-01-01到2017-12-31之間</message>
</field-validator>
</field>
</validators>
結(jié)果展示頁(yè)面:
<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
Created by IntelliJ IDEA.
User: yangcs
Date: 2017/2/8
Time: 14:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>數(shù)據(jù)校驗(yàn)結(jié)果展示</title>
</head>
<body>
姓名:<s:property value="name"></s:property> <br>
年齡:<s:property value="age"></s:property> <br>
日期:<s:property value="date"></s:property>
</body>
</html>
另有非字段類型規(guī)則配置文件示例:
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<validators>
<validator type="requiredstring" short-circuit="true">
<param name="fieldName">name</param>
<param name="trim">true</param>
<message key="aa"></message>
</validator>
<validator type="requiredstring" short-circuit="true">
<param name="fieldName">age</param>
<param name="trim">true</param>
<message>年齡不能為空</message>
</validator>
<validator type="requiredstring" short-circuit="true">
<param name="fieldName">email</param>
<param name="trim">true</param>
<message>郵箱不能為空</message>
</validator>
<validator type="requiredstring" short-circuit="true">
<param name="fieldName">date</param>
<param name="trim">true</param>
<message>日期不能為空</message>
</validator>
<validator type="regex">
<param name="fieldName">name</param>
<param name="expression"><![CDATA[(\w{4,10})]]></param>
<message>姓名要在4-10位之間</message>
</validator>
<validator type="int">
<param name="fieldName">age</param>
<param name="min">0</param>
<param name="max">200</param>
<message>年齡范圍在0-200之間</message>
</validator>
<validator type="email">
<param name="fieldName">email</param>
<message>郵箱格式不正確</message>
</validator>
<validator type="date">
<param name="fieldName">date</param>
<param name="min">2010-01-01</param>
<param name="max">2010-12-31</param>
<message>日期在2010-01-01到2010-12-31之間</message>
</validator>
</validators>
4、客戶端校驗(yàn)方法:
在JSP的<s:form>元素中添加屬性 validate="true";添加后,在校驗(yàn)規(guī)則文件的規(guī)則會(huì)轉(zhuǎn)變?yōu)榭蛻舳诵r?yàn)規(guī)則,即任何校驗(yàn)都不需要接觸服務(wù)器;
需要注意的是:如果直接訪問(wèn)JSP頁(yè)面,并不能體現(xiàn)出客戶端校驗(yàn),只有通過(guò)訪問(wèn)某個(gè)action然后跳轉(zhuǎn)到JSP頁(yè)面才可以讓客戶端校驗(yàn)生效
5、短路校驗(yàn)器
一般來(lái)說(shuō),如果我們?yōu)閚ame配置了兩個(gè)校驗(yàn)器:第一個(gè)是“不能為空”,第二個(gè)是“長(zhǎng)度大于4且小于10”,則如果name字段為空時(shí),則會(huì)同時(shí)輸出這兩條提示,但是實(shí)際上,如果用戶輸入為空的情況下,只應(yīng)該輸出“不能為空”,這就需要短路校驗(yàn)器;
在<validator>或<field-validator>元素中添加short-circut="true"即可;
短路校驗(yàn)器的規(guī)則:
1.當(dāng)非字段校驗(yàn)器校驗(yàn)失敗,則其后的所有字段校驗(yàn)器都不會(huì)執(zhí)行,而不會(huì)影響其他非字段校驗(yàn)器;
2.字段校驗(yàn)器校驗(yàn)失敗時(shí),其后的所有字段校驗(yàn)器都不會(huì)執(zhí)行;
校驗(yàn)器的運(yùn)行順序
1.非字段校驗(yàn)器比字段校驗(yàn)器先執(zhí)行;
2.從前往后執(zhí)行;
6、struts2提供的校驗(yàn)器列表:
- required:必填校驗(yàn)器,要求field的值不能為null)
- requiredstring:必填字符串校驗(yàn)器,要求field的值不能為null,并且長(zhǎng)度大于0,默認(rèn)情況下會(huì)對(duì)字符串去前后空格
- stringlength:字符串長(zhǎng)度校驗(yàn)器,要求field的值必須在指定的范圍內(nèi),否則校驗(yàn)失敗,minLength參數(shù)指定最小長(zhǎng)度,maxLength參數(shù)指定最大長(zhǎng)度,trim參數(shù)指定校驗(yàn)field之前是否去除字符串前后的空格
- regex:正則表達(dá)式校驗(yàn)器,檢查被校驗(yàn)的field是否匹配一個(gè)正則表達(dá)式,expression參數(shù)指定正則表達(dá)式,caseSensitive參數(shù)指定進(jìn)行正則表達(dá)式匹配時(shí),是否區(qū)分大小寫,默認(rèn)值為true
- int:整數(shù)校驗(yàn)器,要求field的整數(shù)值必須在指定范圍內(nèi),min指定最小值,max指定最大值
- double:雙精度浮點(diǎn)數(shù)校驗(yàn)器,要求field的雙精度浮點(diǎn)數(shù)必須在指定范圍內(nèi),min指定最小值,max指定最大值
- fieldexpression:字段OGNL表達(dá)式校驗(yàn)器,要求field滿足一個(gè)ognl表達(dá)式,expression參數(shù)指定ognl表達(dá)式,該邏輯表達(dá)式基于ValueStack進(jìn)行求值,返回true時(shí)校驗(yàn)通過(guò),否則不通過(guò)
- email:郵件地址校驗(yàn)器,要求如果field的值非空,則必須是合法的郵件地址
- url:網(wǎng)址校驗(yàn)器,要求如果field的值非空,則必須是合法的url地址
- date:日期校驗(yàn)器,要求field的日期值必須在指定范圍內(nèi),min指定最小值,max指定最大值
- conversion:轉(zhuǎn)換校驗(yàn)器,指定在類型轉(zhuǎn)換失敗時(shí),提示的錯(cuò)誤信息
- visitor:用于校驗(yàn)action中的復(fù)合屬性,它指定一個(gè)校驗(yàn)文件用于校驗(yàn)復(fù)合屬性中的屬性
- expression:OGNL表達(dá)式校驗(yàn)器,expression參數(shù)指定ognl表達(dá)式,該邏輯表達(dá)式基于ValueStack進(jìn)行求值,返回true時(shí)校驗(yàn)通過(guò),否則不通過(guò),該校驗(yàn)器不可用在字段校驗(yàn)器風(fēng)格的配置中
二、使用自定義的校驗(yàn)器
通過(guò)重寫ActionSupport類的validate()方法,action可實(shí)現(xiàn)自定義的輸入校驗(yàn),validate()方法會(huì)校驗(yàn)action中所有與execute方法簽名相同的方法。
當(dāng)某個(gè)數(shù)據(jù)校驗(yàn)失敗時(shí),我們可以調(diào)用addFieldError()方法往系統(tǒng)的fieldErrors添加校驗(yàn)失敗信息。
如果系統(tǒng)的fieldErrors包含失敗信息,sturts2會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到名為input的result。在input視圖中,可以通過(guò) <s:fielderror/>標(biāo)簽顯示失敗信息。
示例:
輸入頁(yè)面:
<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
Created by IntelliJ IDEA.
User: yangcs
Date: 2017/2/8
Time: 16:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>數(shù)據(jù)校驗(yàn)</title>
</head>
<body>
<s:form action="Action012">
<s:textfield label="姓名(示例:傻逼)" name="name" ></s:textfield>
<s:textfield label="電話(示例:18252040618)" name="mobile"></s:textfield>
<s:textfield label="日期(示例:2017-02-02)" name="date"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
配置了自定義的校驗(yàn)器的action:
package test002;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
import java.util.regex.Pattern;
/**
* Created by yangcs on 2017/2/8.
* 在action中重寫public void validate()方法,自定義校驗(yàn)器,實(shí)現(xiàn)此方法后不需要再配置校驗(yàn)器xml文件
*/
public class Validation02Action extends ActionSupport{
private String name;
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
private String mobile;
private Date date;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String execute() throws Exception{
return SUCCESS;
}
@Override
public void validate() {//validate()會(huì)對(duì)action中的所有方法校驗(yàn)
if(this.name==null || "".equals(this.name.trim())){
this.addFieldError("name", "用戶名不能為空");
}
if(this.mobile==null || "".equals(this.mobile.trim()))
{
this.addFieldError("mobile", "手機(jī)號(hào)不能為空");
}else{
//使用正則表達(dá)式判斷手機(jī)號(hào),第一個(gè)數(shù)字為1,第二個(gè)數(shù)字為3或5或8,后面跟9位數(shù)字
if(!Pattern.compile("^1[358]\\d{8}$").matcher(mobile).matches()){
this.addFieldError("mobile", "手機(jī)號(hào)格式不正確");
}
}
if(this.date==null||"".equals(this.date)){
this.addFieldError("date", "日期不能為空");
}
}
}
action配置:
<action name="Action012" class="test002.Validation02Action">
<result name="success">/JSP/validationResult02.jsp</result>
<result name="input">/JSP/validationError.jsp</result>
</action>
結(jié)果展示頁(yè)面:
<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
Created by IntelliJ IDEA.
User: yangcs
Date: 2017/2/8
Time: 16:09
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>數(shù)據(jù)校驗(yàn)</title>
</head>
<body>
姓名:<s:property value="name"></s:property><br>
電話:<s:property value="mobile"></s:property><br>
日期:<s:property value="date"></s:property>
</body>
</html>
對(duì)action中指定方法進(jìn)行校驗(yàn)
上述方法會(huì)對(duì)action中的所有方法都進(jìn)行輸入校驗(yàn),若只想對(duì)action中的指定方法進(jìn)行校驗(yàn),只需將PersonAction中的validate()方法名稱改成validateXxx()即可,其中Xxx為對(duì)應(yīng)的方法名稱,Xxx的第一個(gè)字母要大寫。
輸入校驗(yàn)的流程
a. 類型轉(zhuǎn)換器對(duì)請(qǐng)求參數(shù)執(zhí)行類型轉(zhuǎn)換,并把轉(zhuǎn)換后的值賦給action中的屬性。
b. 如果在執(zhí)行類型轉(zhuǎn)換的過(guò)程中出現(xiàn)異常,系統(tǒng)會(huì)將異常信息保存到ActionContext,conversionError攔截器將異常信息封裝到fieldErrors里。不管類型轉(zhuǎn)換是否出現(xiàn)異常,都會(huì)進(jìn)入第c步。
c. 系統(tǒng)通過(guò)反射技術(shù)先調(diào)用action中的validateXxx()方法,Xxx為方法名。
d. 再調(diào)用action中的validate()方法。
e. 經(jīng)過(guò)上面4步,如果系統(tǒng)中的fieldErrors存在錯(cuò)誤信息(即存放錯(cuò)誤信息的集合的size大于0),系統(tǒng)自動(dòng)將請(qǐng)求轉(zhuǎn)發(fā)至名稱為input的視圖。如果系統(tǒng)中的fieldErrors沒(méi)有任何信息,系統(tǒng)將執(zhí)行action中的處理方法。