struts2中提供了數據校驗驗證數據例如驗證郵件、數字等。驗證方式有3種:一是通過validate()方法,二是通過xml,三是使用注解方式。
一、初始化
首先定義一個user類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package com.cyw.test; import java.util.date; public class user { private string name; private int age; private string email; public string getname() { return name; } public void setname(string name) { this .name = name; } public int getage() { return age; } public void setage( int age) { this .age = age; } public string getemail() { return email; } public void setemail(string email) { this .email = email; } public date getbirthday() { return birthday; } public void setbirthday(date birthday) { this .birthday = birthday; } private date birthday; } |
二、validate()方法驗證
可以在繼承了actionsupport的action中重寫validate()來進行驗證。validate()方法會在execute()方法執行前執行,僅當數據校驗正確,才執行execute()方法, 如錯誤則將錯誤添加到fielderrors域中,如果定義的action中存在多個邏輯處理方法,且不同的處理邏輯需要不同的校驗規則,這種情況下validate()會對所有處理邏輯使用相同的校驗規則,為了實現不同的校驗邏輯,需要通過validatex()方法,其中x表示處理邏輯的方法名,如果有錯誤系統會返回result name="input"的頁面,所以需要在action中定義一個input的result。我昨天就困在這個地方好久。問了我大學同學才解決,為了這個validate()驗證昨晚一點多都沒睡,雖然ssh框架現在不流行,特別是前幾天struts2報了一個遠程bug,不過想著既然學java了,就系統的學一遍吧。
1.validate()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
package com.cyw.test; import java.text.parseposition; import java.text.simpledateformat; import java.util.arraylist; import java.util.date; import java.util.list; import java.util.regex.matcher; import java.util.regex.pattern; import com.opensymphony.xwork2.actionsupport; public class validatoraction extends actionsupport { private user user; private list<user>userlist= new arraylist<user>(); public list<user> getuserlist() { return userlist; } public void setuserlist(list<user> userlist) { this .userlist = userlist; } @override public string execute() throws exception { if (user== null || this .hasfielderrors()) { return "regist" ; } else { return "success" ; } } public string adduser() { userlist.add(user); return "success" ; } private static final long serialversionuid = 1l; public user getuser() { return user; } public void setuser(user user) { this .user = user; } @override public void validate() { if (user!= null ) { if (!datapass( user.getname(), "^[a-za-z][a-za-z1-9_-]+$" )) { addfielderror( "user.name" , "用戶名(字母開頭 + 數字/字母/下劃線)" ); } if (!datapass(string.format( "%d" , user.getage()) , "(?:[1-9][0-9]?|1[01][0-9]|120)" )) { addfielderror( "user.name" , "年齡0-120之間" ); } date startdate=strtodate( "1900-01-01" ); date enddate=strtodate( "2017-01-01" ); if (user.getbirthday().before(startdate) || user.getbirthday().after(enddate) ) { addfielderror( "birthday" , "出生日期在1900-01-01至2017-01-01之間。" ); } if (!datapass(user.getemail(), "^[a-za-z_]{1,}[0-9]{0,}@(([a-za-z0-9]-*){1,}\\.){1,3}[a-za-z\\-]{1,}$" )) { addfielderror( "email" , "郵箱格式不符合" ); } } } private date strtodate(string strdate) { simpledateformat formatter = new simpledateformat( "yyyy-mm-dd" ); parseposition pos = new parseposition( 0 ); date strtodate = formatter.parse(strdate, pos); return strtodate; } private boolean datapass(string str,string regex) { pattern pattern=pattern.compile(regex,pattern.case_insensitive); matcher matcher =pattern.matcher(str); return matcher.matches(); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?xml version= "1.0" encoding= "utf-8" ?> <!doctype struts public "-//apache software foundation//dtd struts configuration 2.5//en" "http://struts.apache.org/dtds/struts-2.5.dtd" > <struts> < package name= "default" namespace= "" extends = "struts-default" > <action name= "regist" class = "com.cyw.test.validatoraction" > <result name= "regist" >/register.jsp</result> <result name= "success" >/success.jsp</result> <result name= "input" >/register.jsp</result> </action> </ package > </struts> |
2.validatex()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
package com.cyw.test; import java.text.parseposition; import java.text.simpledateformat; import java.util.arraylist; import java.util.date; import java.util.list; import java.util.regex.matcher; import java.util.regex.pattern; import com.opensymphony.xwork2.actionsupport; public class validatoraction extends actionsupport { private user user; private list<user>userlist= new arraylist<user>(); public list<user> getuserlist() { return userlist; } public void setuserlist(list<user> userlist) { this .userlist = userlist; } public string adduser() { if (user== null ) { return "regist" ; } userlist.add(user); return "success" ; } private static final long serialversionuid = 1l; public user getuser() { return user; } public void setuser(user user) { this .user = user; } public void validateadduser() { if (user!= null ) { if (!datapass( user.getname(), "^[a-za-z][a-za-z1-9_-]+$" )) { addfielderror( "user.name" , "用戶名(字母開頭 + 數字/字母/下劃線)" ); } if (!datapass(string.format( "%d" , user.getage()) , "(?:[1-9][0-9]?|1[01][0-9]|120)" )) { addfielderror( "user.name" , "年齡0-120之間" ); } date startdate=strtodate( "1900-01-01" ); date enddate=strtodate( "2017-01-01" ); if (user.getbirthday().before(startdate) || user.getbirthday().after(enddate) ) { addfielderror( "birthday" , "出生日期在1900-01-01至2017-01-01之間。" ); } if (!datapass(user.getemail(), "^[a-za-z_]{1,}[0-9]{0,}@(([a-za-z0-9]-*){1,}\\.){1,3}[a-za-z\\-]{1,}$" )) { addfielderror( "email" , "郵箱格式不符合" ); } } } private date strtodate(string strdate) { simpledateformat formatter = new simpledateformat( "yyyy-mm-dd" ); parseposition pos = new parseposition( 0 ); date strtodate = formatter.parse(strdate, pos); return strtodate; } private boolean datapass(string str,string regex) { pattern pattern=pattern.compile(regex,pattern.case_insensitive); matcher matcher =pattern.matcher(str); return matcher.matches(); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?xml version= "1.0" encoding= "utf-8" ?> <!doctype struts public "-//apache software foundation//dtd struts configuration 2.5//en" "http://struts.apache.org/dtds/struts-2.5.dtd" > <struts> < package name= "default" namespace= "" extends = "struts-default" > <action name= "regist" class = "com.cyw.test.validatoraction" method= "adduser" > <result name= "regist" >/register.jsp</result> <result name= "success" >/success.jsp</result> <result name= "input" >/register.jsp</result> </action> </ package > </struts> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<%@ page language= "java" contenttype= "text/html; charset=utf-8" pageencoding= "utf-8" %> <%@ taglib uri= "/struts-tags" prefix= "struts" %> <!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd" > <html> <head> <meta http-equiv= "content-type" content= "text/html; charset=utf-8" > <title>注冊頁面</title> </head> <body> <struts:fielderror key= "name" ></struts:fielderror> <struts:form action= "regist" method= "post" > <struts:textfield name= "user.name" label= "用戶名" ></struts:textfield> <br/> <struts:textfield name= "user.age" label= "年齡" ></struts:textfield> <br/> <struts:textfield name= "user.birthday" label= "出生日期" ></struts:textfield> <br/> <struts:textfield name= "user.email" label= "郵箱" ></struts:textfield> <br/> <struts:submit value= "注冊" ></struts:submit> </struts:form> </body> </html> |
二、xml驗證
使用validate方法校驗時,如果web應用中存在大量action就需要多次重寫validate方法,因此可以使用xwork的validator框架來對struts2進行數據校驗,減少代碼量。在action包下創建驗證文件xxx-validation.xml,注:當一個action中有多個業務處理方法是,命名規則為:actionname-methodname-validation.xml,其中actionname為action類名,methodname為action中某個業務處理方法的方法名,并且文件的搜索順序與方式一種validate()和validatex()一樣。
這里先注釋掉action的驗證方法,然后新增一個xml驗證文件,最后要在form中增加validate="true"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<?xml version= "1.0" encoding= "utf-8" ?> <!doctype validators public "-//apache struts//xwork validator 1.0.3//en" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd" > <validators> <field name= "user。name" > <field-validator type= "regex" > <param name= "expression" ><![cdata[(\w{ 4 , 20 })]]></param> <message>用戶名必須在 4 到 20 之間,且必須是字母或者數字</message> </field-validator> </field> <field name= "user.email" > <field-validator type= "email" > <message>你的電子郵件地址必須是一個有效的電郵地址</message> </field-validator> </field> <field name= "user.age" > <field-validator type= "int" > <param name= "min" > 1 </param> <param name= "max" > 120 </param> <message>年紀必須在 1 到 120 之間</message> </field-validator> </field> <field name= "user.birthday" > <field-validator type= "date" short -circuit= "true" > <param name= "min" > 1900 - 01 - 01 </param> <param name= "max" > 2050 - 02 - 21 </param> <message>生日在${min}到${max}之間</message> </field-validator> </field> </validators> |
這里遺留了兩個問題,一是錯誤信息不是一次全部顯示出來,如上面兩個圖先顯示兩個錯誤提示,然后將顯示的修改正確之后又顯示其他的,這為什么不是全部顯示出來呢?二是在xml中使用正則表達式驗證怎么不起作用,這個也是個遺留的問題,先把這兩個問題放在這里,等以后再問下其他人,如果哪位讀者知道原因也希望留言告訴博主,先謝過了。
三、注解
1.validations annotation的使用
validations中定義了一些驗證器的數組,用于存放驗證規則,定義如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public @interface validations { //自定義校驗器數組 public customvalidator[] customvalidators() default {}; //字段轉換錯誤校驗器數組 public conversionerrorfieldvalidator[] conversionerrorfields() default {}; //日期范圍校驗器 public daterangefieldvalidator[] daterangefields() default {}; //email校驗器 public emailvalidator[] emails() default {}; //字段表達式校驗器 public fieldexpressionvalidator[] fieldexpressions() default {}; //整數范圍校驗器 public intrangefieldvalidator[] intrangefields() default {}; //必填字段校驗器 public requiredfieldvalidator[] requiredfields() default {}; //必填字符串校驗器 public requiredstringvalidator[] requiredstrings() default {}; //字符串長度校驗器 public stringlengthfieldvalidator[] stringlengthfields() default {}; //url校驗器 public urlvalidator[] urls() default {}; //帶條件的vistor校驗器 public conditionalvisitorfieldvalidator[] conditionalvisitorfields() default {}; //vistor校驗器 public visitorfieldvalidator[] visitorfields() default {}; //正則表達式校驗器 public regexfieldvalidator[] regexfields() default {}; //表達式校驗器 public expressionvalidator[] expressions() default {}; } |
requiredstringvalidator —— 必填字符串校驗器
校驗要求:指定字段不能為null且字符串長度大于0
參數:
- fieldname:校驗字段名
- trim:校驗時取出字符串兩邊的空格,默認為true
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
requiredfieldvalidator —— 必填校驗器
校驗要求:指定字段不能為null
參數:
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
intrangefieldvalidator —— 整數范圍校驗器
校驗要求:int、long、short字段的整數值在指定的范圍內
參數:
- min:指定最小值,可選,沒有則不檢查最小值
- max:指定最大值,可選,沒有則不檢查最大值
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
daterangefieldvalidator —— 日期范圍校驗器
校驗要求:日期在指定的范圍內
參數:
- min:指定最小值,可選,沒有則不檢查最小值
- max:指定最大值,可選,沒有則不檢查最大值
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
emailvalidator —— email地址校驗器
校驗要求:指定的字段為email地址
參數:
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
expressionvalidator —— 表達式校驗器
校驗要求:指定的ongl表達式返回true。
參數:
- expression:ongl表達式
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
urlvalidator —— url校驗器
校驗要求:校驗指定的字段值是否為合法的url
參數:
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
stringlengthfieldvalidator —— 字符串長度校驗器
校驗要求:字符串長度在指定的范圍內
參數:
- minlength:指定最小長度,可選,沒有則不檢查最小長度
- maxlength:指定最大長度,可選,沒有則不檢查最大長度
- trim:校驗時取出字符串兩邊的空格,默認為true
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
conversionerrorfieldvalidator —— 轉換錯誤校驗器
校驗要求:校驗指定字段是否發生類型轉換錯誤
參數:
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
visitorfieldvalidator —— vistor校驗器
說明:普通校驗器只能校驗基本數據類型和字符串類型,該校驗器可以校驗對象里面的屬性。
參數:
- context:用于校驗的context
- appendprefix: 校驗發生錯誤時是否在錯誤信息中添加前最消息
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
regexfieldvalidator —— 正則表達式校驗器
校驗要求:指定字段匹配指定的正則表達式
參數:
- expression:正則表達式
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
conditionalvisitorfieldvalidator —— 帶條件的vistor校驗器
驗證要求:在條件不滿足時,和vistor校驗器功能一樣,條件滿足則不執行vistor校驗
參數:
- fieldname:校驗字段名
- message:校驗失敗時的消息
- key:校驗失敗時返回i18n中指定名稱的消息
customvalidator —— 自定義校驗器
校驗器:自定義校驗器
舉例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package com.cyw.test; import java.text.parseposition; import java.text.simpledateformat; import java.util.arraylist; import java.util.date; import java.util.list; import java.util.regex.matcher; import java.util.regex.pattern; import com.opensymphony.xwork2.actionsupport; import com.opensymphony.xwork2.validator.annotations.validations; import com.opensymphony.xwork2.validator.annotations.*; public class validatoraction extends actionsupport { private user user; private list<user>userlist= new arraylist<user>(); public list<user> getuserlist() { return userlist; } public void setuserlist(list<user> userlist) { this .userlist = userlist; } @validations ( emails={ @emailvalidator (fieldname= "user.email" ,message= "郵件字段的格式不對" )}, conversionerrorfields={ @conversionerrorfieldvalidator (fieldname= "user.age" ,message= "年齡輸入的值轉換錯誤" )}, intrangefields={ @intrangefieldvalidator (fieldname= "user.age" ,min= "0" ,max= "120" ,message= "年齡范圍為0到120" )}, daterangefields={ @daterangefieldvalidator (fieldname= "user.birthday" ,min= "1900-01-01" ,max= "2017-03-30" ,message= "日期輸入不正確" )}, regexfields={ @regexfieldvalidator (regexexpression= "^[a-za-z][a-za-z1-9_-]+$" ,fieldname= "user.name" ,message= "用戶名(字母開頭 + 數字/字母/下劃線)" )} ) public string adduser() { if (user== null ) { return "regist" ; } userlist.add(user); return "success" ; } private static final long serialversionuid = 1l; public user getuser() { return user; } public void setuser(user user) { this .user = user; } } |
結論:
1.action類中使用validations annotation定義驗證。
2.action中,可以在方法上、類上定義驗證annotations,所有的驗證器都將同時作用在映射為action的方法上。
3.action中有多個方法被映射為action時,類上和方法上所有定義的驗證annotations都將作用在每個映射為action的方法上。
4.action中校驗失敗時,返回input邏輯視圖
5.可以使用@skipvalidation跳過所有的驗證檢查,包括自身方法定義的校驗器。
6.可以在action映射中使用如下代碼跳過校驗檢查
1
2
3
|
<interceptor-ref name= "validation" > <param name= "validateannotatedmethodonly" > true </param> </interceptor-ref> |
遺留問題修改:
上面遺留了一個問題,在xml中來做驗證時正則表達式不起作用,保存之后突然想到在注解中用下面的代碼來表示的
regexfields={@regexfieldvalidator(regexexpression="^[a-za-z][a-za-z1-9_-]+$",fieldname="user.name",message="用戶名(字母開頭 + 數字/字母/下劃線)")}
看著參數名和xml中配置的不一樣,會不會是參數名錯誤呢?因為我在網上查的有的用regex或expression,不過都說在提問說不起作用,我懷疑是不是參數名有問題,報著試一試的態度用regexexpression試一試,沒想到還成功了。應該將上面用xml驗證name的地方改成這樣子。
1
2
3
4
5
6
|
<field name= "user.name" > <field-validator type= "regex" > <param name= "regexexpression" ><![cdata[(\^[a-za-z][a-za-z1-9_-]+$)]]></param> <message>用戶名(字母開頭 + 數字/字母/下劃線)</message> </field-validator> </field> |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/5ishare/p/6641756.html?utm_source=tuicool&utm_medium=referral