JSF中的validator
JSF中,有两种为组件注册validator的方法:
1、在组件的标记中直接注册;2、使用<f:validator>标记在组件的标记体中注册。
JSF只提供了3中标准的验证器(当然还有一个非空的验证器),但是它们也足够强大了:
1、<f:validateDoubleRange>
顾名思义是用来验证双精度的数字的
<f:validateDoubleRange minimum="5.1" maximum="6.76" />
2、<f:validateLength>
对输入长度进行验证
<f:validateLength minimum="2" maximum="10" />
注意:即使我们指定了组件的size属性,我们还是要使用Length-Validator,这样可以保证客户端和服务器端都能对输入的长度进行控制。
3、<f:validateLongRange>
可以验证输入的是否为long型
<f:validateLongRange minimum="5" maximum="999999" />
还有一个用处就是可以用它来判断是否输入的为整型的数字
对于非空验证它比较特殊,因为每个输入的组件都会有一个required来声明是否进行非空输入验证。
<h:inputText id="notNullText" required="true" />
TIP:以上这些validator都无法对selectMany family组件起作用,因为它的value属性是数组型的,没法转换为validator可以识别并验证的类型。
还有就是可以在一个组件中注册多个validator:
<h:inputText id="multiInput" required="true">
<f:validateLength minimum="2" maximum="3"/>
<f:validateLongRange minimum="10" maximum="999" />
</h:inputText>
它们进行验证的顺序是按照在标记中加载的顺序来进行的。
在JSF中开发自定义的Validator
JSF中,对于自定义的validator可以使用两种方法将其注册到组件。
1、开发自定义的标记,这个稍微复杂一点点,但是通用性和功能都比较强大
2、在JSF的配置文件中配置id,然后在组件体中使用<f:validator validatorId="[id]"/>,这种方法无法设置自定义validator的任何属性,所以功能上稍弱。
原理:
一、开发validator首先需要继承javax.faces.validator.Validator接口,同时如果需要在请求间保存你的validator自己的属性的话,还可以同时继承StateHolder接口。
二、EditableValueHolder保持了所有Validator实例,可以使用后台的代码或者前台显示声明的方法来向其中添加新的Validator实例。
三、在Request运行生命周期中,JSF调用输入控制validate()方法,执行与之相关的Validator。
四、JSF配置文件中,可以定义Validator的标识符,但是一般我们会在自定义的validator中使用常量来表示,如:
public final String VALIDATOR_ID = "com.angus.cusValidator";
五、Validator接口定义了一个方法:
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException;
当你使用这个方法时,要检查value值是不是你所需要的类型,如果不是,则要抛出一个新的ValidatorException异常;
ValidatorException异常有两个构造器:1、只传一个FacesMessage实例的参;2、一个FacesMessage和一个原始的Throwable实例;
例:
public void validate (FacesContect context, UIComponent component, Object value) {
....
if(!isValid(value)) {
...
throw new ValidatorException(new FacesMessage(messageText,null));
}
}
protected boolean isValid(String value) {
...
return pattern.matcher(value).matches();
}
这里,将isValid()方法与validate()方法分开是一个比较好的做法,因为在测试中,你不用费尽心思来给validate()方法提供一个FacesContext的实例。
六、利用StateHolder接口来保存validator属性(Validator会被自动地记录在UIInput中)。这时,自定义的validator要有一个无参的构造器,这样它才能被Application对象中的createValidator()方法创建出来。