本文参考 http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2630
?
在 自定义验证器 中,我们的验证器只能验证一种pattern(.+[0-9]+),我们希望可以在JSF页面上自定义匹配的pattern,然而由于我们使用<f: validator>这个通用的验证器标签,为了要能提供pattern属性,我们可以使用<f:attribute>标签来设置,例如:
.... <h:inputSecret value="#{user.password}" required="true"> <f:validator validatorId="bruce.zhao.Password"/> <f:attribute name="pattern" value=".+[0-9]+"/> </h:inputSecret><p> ....?
?使用<f:attribute>标签来设定属性,接着我们可以如下取得所设定的属性:
.... public void validate(FacesContext context, UIComponent component, Object obj) throws ValidatorException { .... String pattern = (String) component.getAttributes().get("pattern"); .... } ....?
?
您也可以开发自己的一组验证标签,并提供相关属性设定,这需要了解JSP Tag Library的编写,所以请您先参考 JSP/Servlet 中有关于JSP Tag Library的介绍。
要开发验证器转用标签,您可以直接继承javax.faces.webapp.ValidatorTag,这个类可以帮您处理大部份的细节,您所需要的,就是重新定义它的createValidator()方法,我们以改写 自定义验证器 中的PasswordValidator为例:PasswordValidator.java
package bruce.zhao; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; public class PasswordValidator implements Validator { private String pattern; public void setPattern(String pattern) { this.pattern = pattern; } public void validate(FacesContext context, UIComponent component, Object obj) throws ValidatorException { String password = (String) obj; if(password.length() < 6) { FacesMessage message = new FacesMessage( FacesMessage.SEVERITY_ERROR, "字符长度小于6", "字符长度不得小于6"); throw new ValidatorException(message); } if(pattern != null && !password.matches(pattern)) { FacesMessage message = new FacesMessage( FacesMessage.SEVERITY_ERROR, "密码必须包括字符与数字", "密码必须是字符加数字所组成"); throw new ValidatorException(message); } } }?
主要的差别是我们提供了pattern属性,在validate()方法中进行验证时,是根据我们所设定的pattern属性,接着我们继承javax.faces.webapp.ValidatorTag来编写自己的验证标签:PasswordValidatorTag.java
package bruce.zhao; import javax.faces.application.Application; import javax.faces.context.FacesContext; import javax.faces.validator.Validator; import javax.faces.webapp.ValidatorTag; public class PasswordValidatorTag extends ValidatorTag { private String pattern; public void setPattern(String pattern) { this.pattern = pattern; } protected Validator createValidator() { Application application = FacesContext.getCurrentInstance(). getApplication(); PasswordValidator validator = (PasswordValidator) application.createValidator( "bruce.zhao.Password"); validator.setPattern(pattern); return validator; } }?
?application.createValidator()方法建立验证器对象时,是根据在faces-config.xml中注册验证器的标识(Validater ID):faces-config.xml
<?xml version="1.0"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> <faces-config> .... <validator> <validator-id> bruce.zhao.Password </validator-id> <validator-class> bruce.zhao.PasswordValidator </validator-class> </validator>?
?剩下来的工作,就是布署tld描述文件了,我们简单的定义一下:
<?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.0"> <description>PasswordValidator Tag</description> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>co</short-name> <uri>http://whoosh.iteye.com</uri> <tag> <description>PasswordValidator</description> <name>passwordValidator</name> <tag-class> bruce.zhao.PasswordValidatorTag </tag-class> <body-content>empty</body-content> <attribute> <name>pattern</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> </taglib>?
?而我们的index.jsp改写如下:index.jsp
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="/WEB-INF/taglib.tld" prefix="co" %> <%@page contentType="text/html;charset=GB2312"%> <html> <head> <title>验证器示范</title> </head> <body> <f:view> <h:messages layout="table" style="color:red"/> <h:form> <h3>请输入您的名称</h3> <h:outputText value="#{user.errMessage}"/><p> 名称: <h:inputText value="#{user.name}" required="true"/><p> 密码: <h:inputSecret value="#{user.password}" required="true"> <co:passwordValidator pattern=".+[0-9]+"/> </h:inputSecret> <p> <h:commandButton value="送出" action="#{user.verify}"/> </h:form> </f:view> </body> </html>?
?主要的差别是,我们使用了自己的验证器标签:
<co:passwordValidator pattern=".+[0-9]+"/>
?如果要自定义转换器标签,方法也是类似,您要作的是继承javax.faces.webapp.ConverterTag,并重新定义其createConverter()方法。