在Struts中对用户输入信息的校验一般在FromBean中进行(除非需要访问数据库进行诸如登录信息的校验,因为这是Action的工作),本文将阐述如何在Struts中实现可配置的信息校验。
一、在FormBean中手工实现
最简单的方法是直接在FormBean中重写ActionForm类的validate方法,validate方法签名如下:
public
ActionErrors validate(ActionMapping mapping, HttpServletRequest req)
比如需要校验age字段必须填写数字:
1
public
ActionErrors validate(ActionMapping mapping, HttpServletRequest req)
{
2
ActionErrors errors = new ActionErrors();
3
4
String age = this.getAge();
5
if(!this.isNumber(age))
{ // isNumber() is not implemented
6
errors.add(
,
);
7
}
8
9
return errors;
10
}
在form提交后,容器会调用validate方法对表单数据进行校验,如果返回的ActionErrors为空(即校验通过),则将FormBean提交Action,否则重定向到提交form的页面。
这种方法实现简单,直观,容易测试、调试,但不可避免地存在以下缺点:
1、很难重用,导致重复开发
有很多校验逻辑在整个网站中是相同的,比如上述的数字校验,还有email校验、长度校验等等,而通过覆盖validate方法很难对这些校验过程进行重用,除非定义一些helper类封装校验方法(比如上述的isNumber())。而当需要为另一个FormBean加入相同的校验逻辑时必须重复地覆盖validate方法
2、难于扩展
当要对一个表单增、删、改校验逻辑时必须修改validate方法,重新打包、部署
3、不可配置
因为校验逻辑硬编码于class文件中,运行时不可能做到灵活地配置校验逻辑
因此,Struts中加入了另一种更灵活的校验机制:
二、使用Validator
Validator提供了一种基于xml配置文件的校验模型,要使用这一模型必须做如下实现:
1、FormBean继承org.apache.struts.validator.ValidatorForm而不是ActionForm
2、不覆盖validate方法
3、创建validator-rules.xml及validation.xml文件
validator-rules.xml定义了可用来配置的校验逻辑,如:
1
<
form-validation
>
2
<
global
>
3
<
validator
name
="required"
4
classname
="org.apache.struts.validator.FieldChecks"
5
method
="validateRequired"
6
methodParams
="java.lang.Object,
7
org.apache.commons.validator.ValidatorAction,
8
org.apache.commons.validator.Field,
9
org.apache.struts.action.ActionMessages,
10
org.apache.commons.validator.Validator,
11
javax.servlet.http.HttpServletRequest"
12
msg
="errors.required"
/>
13
<
validator
name
="requiredif"
14
classname
="org.apache.struts.validator.FieldChecks"
15
method
="validateRequiredIf"
16
methodParams
="java.lang.Object,
17
org.apache.commons.validator.ValidatorAction,
18
org.apache.commons.validator.Field,
19
org.apache.struts.action.ActionMessages,
20
org.apache.commons.validator.Validator,
21
javax.servlet.http.HttpServletRequest"
22
msg
="errors.required"
/>
23
<
validator
name
="validwhen"
24
msg
="errors.required"
25
classname
="org.apache.struts.validator.validwhen.ValidWhen"
26
method
="validateValidWhen"
27
methodParams
="java.lang.Object,
28
org.apache.commons.validator.ValidatorAction,
29
org.apache.commons.validator.Field,
30
org.apache.struts.action.ActionMessages,
31
org.apache.commons.validator.Validator,
32
javax.servlet.http.HttpServletRequest"
/>
33
<
validator
name
="minlength"
34
classname
="org.apache.struts.validator.FieldChecks"
35
method
="validateMinLength"
36
methodParams
="java.lang.Object,
37
org.apache.commons.validator.ValidatorAction,
38
org.apache.commons.validator.Field,
39
org.apache.struts.action.ActionMessages,
40
org.apache.commons.validator.Validator,
41
javax.servlet.http.HttpServletRequest"
42
depends
=""
43
msg
="errors.minlength"
44
jsFunction
="org.apache.commons.validator.javascript.validateMinLength"
/>
45
<
validator
name
="maxlength"
46
classname
="org.apache.struts.validator.FieldChecks"
47
method
="validateMaxLength"
48
methodParams
="java.lang.Object,
49
org.apache.commons.validator.ValidatorAction,
50
org.apache.commons.validator.Field,
51
org.apache.struts.action.ActionMessages,
52
org.apache.commons.validator.Validator,
53
javax.servlet.http.HttpServletRequest"
54
depends
=""
55
msg
="errors.maxlength"
56
jsFunction
="org.apache.commons.validator.javascript.validateMaxLength"
/>
57
<
validator
name
="mask"
58
classname
="org.apache.struts.validator.FieldChecks"
59
method
="validateMask"
60
methodParams
="java.lang.Object,
61
org.apache.commons.validator.ValidatorAction,
62
org.apache.commons.validator.Field,
63
org.apache.struts.action.ActionMessages,
64
org.apache.commons.validator.Validator,
65
javax.servlet.http.HttpServletRequest"
66
depends
=""
67
msg
="errors.invalid"
/>
68
<
validator
name
="byte"
69
classname
="org.apache.struts.validator.FieldChecks"
70
method
="validateByte"
71
methodParams
="java.lang.Object,
72
org.apache.commons.validator.ValidatorAction,
73
org.apache.commons.validator.Field,
74
org.apache.struts.action.ActionMessages,
75
org.apache.commons.validator.Validator,
76
javax.servlet.http.HttpServletRequest"
77
depends
=""
78
msg
="errors.byte"
79
jsFunctionName
="ByteValidations"
/>
80
<
validator
name
="short"
81
classname
="org.apache.struts.validator.FieldChecks"
82
method
="validateShort"
83
methodParams
="java.lang.Object,
84
org.apache.commons.validator.ValidatorAction,
85
org.apache.commons.validator.Field,
86
org.apache.struts.action.ActionMessages,
87
org.apache.commons.validator.Validator,
88
javax.servlet.http.HttpServletRequest"
89
depends
=""
90
msg
="errors.short"
91
jsFunctionName
="ShortValidations"
/>
92
<
validator
name
="integer"
93
classname
="org.apache.struts.validator.FieldChecks"
94
method
="validateInteger"
95
methodParams
="java.lang.Object,
96
org.apache.commons.validator.ValidatorAction,
97
org.apache.commons.validator.Field,
98
org.apache.struts.action.ActionMessages,
99
org.apache.commons.validator.Validator,
100
javax.servlet.http.HttpServletRequest"
101
depends
=""
102
msg
="errors.integer"
103
jsFunctionName
="IntegerValidations"
/>
104
<
validator
name
="long"
105
classname
="org.apache.struts.validator.FieldChecks"
106
method
="validateLong"
107
methodParams
="java.lang.Object,
108
org.apache.commons.validator.ValidatorAction,
109
org.apache.commons.validator.Field,
110
org.apache.struts.action.ActionMessages,
111
org.apache.commons.validator.Validator,
112
javax.servlet.http.HttpServletRequest"
113
depends
=""
114
msg
="errors.long"
/>
115
<
validator
name
="float"
116
classname
="org.apache.struts.validator.FieldChecks"
117
method
="validateFloat"
118
methodParams
="java.lang.Object,
119
org.apache.commons.validator.ValidatorAction,
120
org.apache.commons.validator.Field,
121
org.apache.struts.action.ActionMessages,
122
org.apache.commons.validator.Validator,
123
javax.servlet.http.HttpServletRequest"
124
depends
=""
125
msg
="errors.float"
126
jsFunctionName
="FloatValidations"
/>
127
<
validator
name
="double"
128
classname
="org.apache.struts.validator.FieldChecks"
129
method
="validateDouble"
130
methodParams
="java.lang.Object,
131
org.apache.commons.validator.ValidatorAction,
132
org.apache.commons.validator.Field,
133
org.apache.struts.action.ActionMessages,
134
org.apache.commons.validator.Validator,
135
javax.servlet.http.HttpServletRequest"
136
depends
=""
137
msg
="errors.double"
/>
138
<
validator
name
="date"
139
classname
="org.apache.struts.validator.FieldChecks"
140
method
="validateDate"
141
methodParams
="java.lang.Object,
142
org.apache.commons.validator.ValidatorAction,
143
org.apache.commons.validator.Field,
144
org.apache.struts.action.ActionMessages,
145
org.apache.commons.validator.Validator,
146
javax.servlet.http.HttpServletRequest"
147
depends
=""
148
msg
="errors.date"
149
jsFunctionName
="DateValidations"
/>
150
<
validator
name
="intRange"
151
classname
="org.apache.struts.validator.FieldChecks"
152
method
="validateIntRange"
153
methodParams
="java.lang.Object,
154
org.apache.commons.validator.ValidatorAction,
155
org.apache.commons.validator.Field,
156
org.apache.struts.action.ActionMessages,
157
org.apache.commons.validator.Validator,
158
javax.servlet.http.HttpServletRequest"
159
depends
="integer"
160
msg
="errors.range"
/>
161
<
validator
name
="floatRange"
162
classname
="org.apache.struts.validator.FieldChecks"
163
method
="validateFloatRange"
164
methodParams
="java.lang.Object,
165
org.apache.commons.validator.ValidatorAction,
166
org.apache.commons.validator.Field,
167
org.apache.struts.action.ActionMessages,
168
org.apache.commons.validator.Validator,
169
javax.servlet.http.HttpServletRequest"
170
depends
="float"
171
msg
="errors.range"
/>
172
<
validator
name
="doubleRange"
173
classname
="org.apache.struts.validator.FieldChecks"
174
method
="validateDoubleRange"
175
methodParams
="java.lang.Object,
176
org.apache.commons.validator.ValidatorAction,
177
org.apache.commons.validator.Field,
178
org.apache.struts.action.ActionMessages,
179
org.apache.commons.validator.Validator,
180
javax.servlet.http.HttpServletRequest"
181
depends
="double"
182
msg
="errors.range"
/>
183
<
validator
name
="creditCard"
184
classname
="org.apache.struts.validator.FieldChecks"
185
method
="validateCreditCard"
186
methodParams
="java.lang.Object,
187
org.apache.commons.validator.ValidatorAction,
188
org.apache.commons.validator.Field,
189
org.apache.struts.action.ActionMessages,
190
org.apache.commons.validator.Validator,
191
javax.servlet.http.HttpServletRequest"
192
depends
=""
193
msg
="errors.creditcard"
/>
194
<
validator
name
="email"
195
classname
="org.apache.struts.validator.FieldChecks"
196
method
="validateEmail"
197
methodParams
="java.lang.Object,
198
org.apache.commons.validator.ValidatorAction,
199
org.apache.commons.validator.Field,
200
org.apache.struts.action.ActionMessages,
201
org.apache.commons.validator.Validator,
202
javax.servlet.http.HttpServletRequest"
203
depends
=""
204
msg
="errors.email"
/>
205
<
validator
name
="url"
206
classname
="org.apache.struts.validator.FieldChecks"
207
method
="validateUrl"
208
methodParams
="java.lang.Object,
209
org.apache.commons.validator.ValidatorAction,
210
org.apache.commons.validator.Field,
211
org.apache.struts.action.ActionMessages,
212
org.apache.commons.validator.Validator,
213
javax.servlet.http.HttpServletRequest"
214
depends
=""
215
msg
="errors.url"
/>
216
<!--
217
This simply allows struts to include the validateUtilities into a page, it should
218
not be used as a validation rule.
219
-->
220
<
validator
name
="includeJavaScriptUtilities"
221
classname
=""
222
method
=""
223
methodParams
=""
224
depends
=""
225
msg
=""
226
jsFunction
="org.apache.commons.validator.javascript.validateUtilities"
/>
227
<
validator
name
="codeinput"
228
classname
="consultII.web.utils.MyValidator"
229
method
="validateCodeInput"
230
methodParams
="java.lang.Object,
231
org.apache.commons.validator.ValidatorAction,
232
org.apache.commons.validator.Field,
233
org.apache.struts.action.ActionMessages,
234
javax.servlet.http.HttpServletRequest"
235
msg
="errors.code"
/>
236
<
validator
name
="userinfo"
237
classname
="consultII.web.utils.MyValidator"
238
method
="validateUserInfo"
239
methodParams
="java.lang.Object,
240
org.apache.commons.validator.ValidatorAction,
241
org.apache.commons.validator.Field,
242
org.apache.struts.action.ActionMessages,
243
javax.servlet.http.HttpServletRequest"
244
msg
="errors.info"
/>
245
</
global
>
246
</
form-validation
>
该配置文件的具体格式请查阅Struts的
官方文档。可以看出其中对很多常用的校验逻辑进行了封装,比如数字校验(92行到103行),长度校验(33行到56行)等。
而validation.xml则是Validator的核心,其中可对各个FormBean中需要校验字段及校验逻辑进行灵活的配置:
1
<
form-validation
>
2
<
formset
>
3
<
form
name
="login"
>
4
<
field
property
="username"
depends
="required"
/>
5
<
field
property
="password"
depends
="required"
/>
6
<
field
property
="input"
depends
="required,codeinput"
/>
7
</
form
>
8
<
form
name
="search"
>
9
<
field
property
="keyword"
depends
="required"
/>
10
</
form
>
11
<
form
name
="signin"
>
12
<
field
property
="username"
depends
="required"
/>
13
<
field
property
="password"
depends
="required"
/>
14
<
field
property
="passagain"
depends
="required"
/>
15
<
field
property
="question"
depends
="required,userinfo"
/>
16
<
field
property
="answer"
depends
="required,userinfo"
/>
17
<
field
property
="age"
depends
="required,integer"
/>
18
<
field
property
="input"
depends
="required,codeinput"
/>
19
<
field
property
="email"
depends
="email"
/>
20
</
form
>
21
<
form
name
="ask"
>
22
<
field
property
="content"
depends
="required"
/>
23
</
form
>
24
</
formset
>
25
</
form-validation
>
26
具体格式可查阅官方文档,如上例,3到5行定义了需要对名为“loging”的FormBean的“username”、“password”分别进行“required”校验(即必填字段)。校验逻辑之间可以组合,如第6行的“required,codeinput”,定义了先进行required校验,通过了再进行codeinput校验。
与在validate方法内进行校验相比,使用Validator的优势就很明显了,可重用(从上述xml文件可以看出对很多字段都进行了required校验);可灵活配置、扩展,只需修改validation.xml文件就可以改变校验逻辑。