在Struts中对用户输入信息的校验一般在FromBean中进行(除非需要访问数据库进行诸如登录信息的校验,因为这是Action的工作),本文将阐述如何在Struts中实现可配置的信息校验。
一、在FormBean中手工实现
最简单的方法是直接在FormBean中重写ActionForm类的validate方法,validate方法签名如下:
比如需要校验age字段必须填写数字:
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定义了可用来配置的校验逻辑,如:
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中需要校验字段及校验逻辑进行灵活的配置:
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文件就可以改变校验逻辑。