在JSF中开发自定义的Validator(一)

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()方法创建出来。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页