自定义验证器
我们已经看到了,只要实现了Validator接口的类都可以作为验证器。我们看一下Validator接口的源码:
public interface Validator<T> {
void setDefaultMessage(String message);
String getDefaultMessage();
String getMessage(Object object);
void setMessageKey(String key);
String getMessageKey();
void setMessageParameters(String[] messageParameters);
String[] getMessageParameters();
void setValidatorContext(ValidatorContext validatorContext);
void validate(Object object) throws ValidationException;
void setValidatorType(String type);
String getValidatorType();
void setValueStack(ValueStack stack);
}
Validation拦截器负责加载和执行各种验证器。在加载一个验证器之后,拦截器调用那个验证器的setValidatorContext方法,把当前的ValidatorContext对象传递给它,这样验证器就可以访问当前动作了。接下来拦截器调用验证器的validate方法,并把需要验证的对象传递进去。所以validate方式是我们在编写验证器时必须实现的方法。
ValidatorSupport类实现了Validator接口,并增加了一些扩展方法:
getFieldValue方法用于获取验证字段的值
addActionError方法用于添加一个Action级别的错误信息
addFieldError用于添加一个字段级别的错误信息。
需要注意的是他是一个抽象类,我们需要继承它或他的子类。一般如果我们要实现一个字段验证器,那么我们会选择继承他的(抽象)子类FieldValidatorSupport,如果我们需要实现一个非字段验证器,那么我们一般会直接继承ValidatorSupport类。在验证失败之后,如果我们实现的是字段验证器,那么需要使用addFieldError方法添加错误信息,如果是非字段验证器,那么使用addActionError方法添加错误信息。
下面我们动手实现一个自定义的字段验证器验证器:
MyValidator.java
public class MyValidator extends FieldValidatorSupport {
public void validate(Object object) throws ValidationException {
String fieldName = getFieldName();
Object obj = getFieldValue(fieldName,object);
if(!(obj instanceof String)){
addFieldError(fieldName,obj);
}else{
String fieldValue = (String)obj;
if(fieldValue.length()==0||fieldValue.equals("admin")){
addFieldError(fieldName,obj);
}
}
}
}
UserAction.java略
input.jsp
<body>
<s:if
test="hasFieldErrors()">
<s:iterator
value="fieldErrors">
<font
color="#FF0000"><s:property
value="value[0]"/></font><br>
</s:iterator>
</s:if>
<form
action="user.action"
method="post">
username : <input
type="text"
name="userName"/><br/>
password : <input
type="password"
name="password"/>
<input
type="submit"
value="submit"/>
</form>
</body>
success.jsp略
我们的验证器实现了还需要我们进行注册,需要在Src(classpath)下新建一个validators.xml的配置文件,安装框架内建验证器声明的格式来声明我们的自定义验证器。
<?xml
version="1.0"
encoding="UTF-8"?>
<!DOCTYPE
validators PUBLIC
"-//Apache Struts//XWork Validator Config1.0//EN"
"http://struts.apache.org/dtds/xwork-validator-config-1.0.dtd">
<validators>
<validator
name="myvalidator"
class="action.MyValidator"></validator>
</validators>
UserAction-validator.xml
<?xml
version="1.0"
encoding="UTF-8"?>
<!DOCTYPE
validators PUBLIC
"-//Apache Struts//XWork Validator1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<field
name="userName">
<field-validator
type="myvalidator">
<message>用户名格式不正确</message>
</field-validator>
</field>
<field
name="password">
<field-validator
type="requiredstring">
<param
name="trim">true</param>
<message>passwordcannot be empty</message>
</field-validator>
<field-validator
type="stringlength">
<param
name="minLength">6</param>
<param
name="maxLength">10</param>
<message>
the length of password mustbetween 6 and 10
</message>
</field-validator>
</field>
</validators>
测试:
提交结果:
我们还可以在自定义拦截器中增加一些属性,这样我们可以在配置文件中通过<param>元素来设置,要保证这些属性都有相应的get和set方法。
错误消息本地化和参数化
上面我们看到的验证失败的错误信息都是我们硬编码在<message>元素中的。Struts2还提供了将这些消息本地化和参数化的能力。我们可以在<message>标签是使用OGNL表达式来引用Action的属性,和使用getText方法来获取我们在ActionClass.properties中配置的本地消息。我们将前面的判断用户输入两个数的例子修改一下。
NumberAction.java略。
NumberAction.properties
message=max\u7684\u503C\u5FC5\u987B\u5927\u4E8Emin\u7684\u503C(max的值必须大于min的值)
NumberAction-validator.xml
<?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>
<validator
type="expression">
<param
name="expression">max > min</param>
<message>${getText("message")}</message>
</validator>
<field
name="max">
<field-validator
type="int">
<param
name="max">10</param>
<param
name="min">5</param>
<message>max的值必须介于5-10之间</message>
</field-validator>
</field>
</validators>
input.jsp略
测试:
提交结果:
我们还可以在<message>元素中使用${max}和${min}的形式来引用Action的max和min属性。
注:Struts2手册中说如果我们使用了validators.xml文件来注册我们自定义的验证器,那么需要我们将默认验证器在validator中重新定义一次,但是从上面的实例可以看住,虽然我没有在validators.xml中重新声明int验证器,但是它还是能够起作用!
验证器的查找顺序
Struts2的验证框架为了使验证信息通用,指定了较为复杂的验证继承关系,当验证框架需要验证一个Action的时候,会按照以下的优先级收集验证信息:
父类-validation.xml
父类-别名-validation.xml
接口-validation.xml
接口-别名-validation.xml
Action类名-validation.xml
Action类名-别名-validation.xml
别名其实对应的就是<action>元素的method属性的值,因此,虽然看着很多,其实我们只需要记住基本的顺序是:父类 >
接口 > Action类 就可以了。
这里还需要强调一点,接口-validation.xml优先于Action类名-validation.xml的含义,并不是找到了接口-validation.xml就不管Action类名-validation.xml,而是对于同名的字段验证器来说,两个验证都要进行,不过接口-validation.xml中的验证先于Action类名-validation.xml中的验证进行。
需要注意的是着写顺序并不是覆盖关系,找到的验证器都会被执行,只是会按照查找的循序来执行这些验证器。
验证短路
验证短路就是一个字段在多个验证器验证的过程中,一出现验证失败,那么后续的验证器就不在执行了。如使用验证短路,只需要在配置验证器的时候将short-circuit属性设置为true(大多数都有个short-circuit属性)即可。我们在编写自定义的验证器时,如果要是验证器具有验证短路功能,需要验证器实现ShortCircuitableValidator接口。如果一个一个非字段验证器设置了短路,那么一旦验证失败将终止整个验证过程。
客户端验证
使用Struts2的验证器和标签结合还能够实现客户端验证功能,但是有两个条件:
(1).struts2标签的form的主题(theme)一定不能设为simple。
(2). 将form的validate属性设为true。
这样客户端就会根据相应的action的xml验证文件产生一个js对客户端进行验证。
一般开发中只使用struts2的服务端验证,而不使用struts2的客户端验证。效果还不如我们自己动手写js来进行客户端验证。
分享到:
相关推荐
Struts2 和Struts1同样也提供了校验框架,但在Struts2 已经不再把校验框架做为一个插件,而是已经内置到了Struts2中,而且配置起来更为简单方便,功能也更强大。
struts2学习笔记!因为还没有全部学完,所以分部分分享!主要内容:struts.xml配置,web.xml配置 Action要点!全局类型转换,部分类型转换,类型转换文件 类型装换错误的处理问题局部使用,把中文汉字转换为编码 struts2对...
Struts2环境搭建 Struts2类型转换 Struts2输入校验 拦截器 文件的上传与下载 Struts2的国际化 深入探析 struts2与servlet API耦合方法
struts2学习笔记,详细说明了struts2框架的执行流程,类型转换,输入校验和国际化等等
更强大、更易用输入校验功能 整合Ajax支持:json插件 Struts2的今生前世: 1.早期开发模型Servlet+JSP+JavaBean显得力不从心: 流程凌乱、数据传递无序、缺乏辅助功能。 2.MVC模式的轻量级Web应
NULL 博文链接:https://zhaolianyang.iteye.com/blog/865509
NULL 博文链接:https://zhaolianyang.iteye.com/blog/867028
NULL 博文链接:https://zhaolianyang.iteye.com/blog/859890
基于 Struts2.1.8 包括Struts2的基本应用、文件上传、拦截器、输入校验、国际化、OGNL表达式、Struts2标签等内容。
自己写的学习笔记, 绝对真实可靠,内容很充实,而且突出重点,
NULL 博文链接:https://zhaolianyang.iteye.com/blog/869320
NULL 博文链接:https://zhaolianyang.iteye.com/blog/869617
struts2框架的输入校验与校验框架,这都是上课的总结笔记
手工编写代码实现对action中所有方法输入校验 博文链接:https://wuzhaohuixy-qq-com.iteye.com/blog/710102
主要介绍Struts2中的数据校验,通过一个简单的例子来说明,希望能给大家做一个参考。
《跟我学Java Web》内容包括搭建Web开发环境、HTML相关技术基础知识、...输入校验、国际化、Struts2的各种标签、对Ajax的支持等)、Spring2.5(容器、装配Java Bean、JDBC和Hibernate模板等)以及Hibernate3技术详解...