JSF2中自定义Validator

在JSF2中实现字段验证的地方有很多,比如说在setter方法内,在action方法内可以对字段进行验证. 在页面,也可以通过requeird属性和converter对字段进行验证,还可以自己定义Converter类来对字段进行验证.下面记录一下对邮箱的验证实现

1. 定义EmailValidator类,实现Validator接口和StateHolder接口. Validator接口是一定要实现的,对于StateHolder接口,如果没有属性从页面传过来,没必要实现。但是我们这里从页面传过来一个Pattern属性,来实现带属性的Validator实现。因为JSF2会在第一次请求的呈现响应阶段会新建Validator实例,并将属性的值从页面传给Validator实例。然而Jsf2会在请求同一个页面的重建组件数阶段重新实例化Validator实例,但并不会把页面是的属性值自动赋上,所以就需要实现StateHolder接口来实现存储属性值的功能,以便在第二此请求中继续使用第一次实例化时候的属性值。StateHolder接口中包含restoreState和saveState方法,saveState方法会在请求的呈现响应阶段调用,restoreState方法会在请求的重建组件树阶段调用:

 

public class EmailValidator implements Validator, StateHolder {
	private String pattern;

	public EmailValidator() {
		System.out.println("EmailValidator created");
	}
	@Override
	public void validate(FacesContext context, UIComponent arg1, Object arg2)
			throws ValidatorException {
		String noValid = ContextUtil.getI18NMessage(context, "#{msg.emailNotValid}");
		String email = (String) arg2;
		Pattern p = null;
		p = Pattern.compile(pattern);
		Matcher matcher = p.matcher(email);
		if (!matcher.matches()) {
			FacesMessage message = new FacesMessage();
			message.setDetail(noValid);
			message.setSummary(noValid);
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(message);
		}
	}

	public String getPattern() {
		return pattern;
	}

	public void setPattern(String pattern) {
		System.out.println("setPattern pattern: "+pattern);
		this.pattern = pattern;
	}


	@Override
	public boolean isTransient() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void restoreState(FacesContext arg0, Object arg1) {
		System.out.println("restoreState pattern: "+arg1);
		this.pattern = (String)arg1;

	}

	@Override
	public Object saveState(FacesContext arg0) {
		System.out.println("saveState:...");
		return getPattern();

	}

	@Override
	public void setTransient(boolean arg0) {

	}

}

 

 在validator方法中,如果验证不成功,直接拋出一个异常,并包装上一些自定义的国际化消息就可以了。

 Validator类实现了,但要把它实现成页面上的一个标签,还需要实现一个Tag类:

public class EmailValidatorTag extends ValidatorImplTag {

	private static final long serialVersionUID = 1L;
	private String pattern;

	public EmailValidatorTag() {
		super();
	}
	
	public String getPattern() {
		return pattern;
	}

	public void setPattern(String pattern) {
		this.pattern = pattern;
	}

	@Override
	protected Validator createValidator() throws JspException {
		setValidatorIdString("com.bond.validator.EmailValidator");
		EmailValidator v = (EmailValidator)super.createValidator();
		v.setPattern(getPattern());
		return v;
	}

}

 在createValidator方法中setValidatorIdString方法中的字符串一定要和faces-config.xml中配置的Validator的<validator-id>中的字符串一样,

这样Jsf2就知道实例化那一个验证器了。

新建了Tag类还需要提供一个tld文件对这个类进行描述tag.tld:

<?xml version="1.0" encoding="UTF-8"?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"

version="2.1">

<description>This tag library implements the standard JSF HTML tags.</description>

<display-name>JSF Validator tag library.</display-name>

<tlib-version>1.2</tlib-version>

<short-name>t</short-name>

<tag>

<name>emailValidator</name>

<tag-class>com.bond.tag.EmailValidatorTag</tag-class>

<body-content>JSP</body-content>

<attribute>

<name>pattern</name>

<required>true</required>

<rtexprvalue>false</rtexprvalue>

</attribute>

</tag>

</taglib>

直接放在web-inf下就可以了

faces-config.xml中的配置:

<validator>

<validator-id>com.bond.validator.EmailValidator</validator-id>

<validator-class>com.bond.validator.EmailValidator</validator-class>

</validator>

这样就可以在页面上应用这个验证器了:

<%@ taglib prefix="t" uri="/WEB-INF/tag.tld"%>

 

<h:outputText value="#{msg.email}"></h:outputText>

<h:inputText value="#{userBean.email}">

<t:emailValidator

pattern="^[_a-z0-9]+@([_a-z0-9]+\\.)+[a-z0-9]{2,3}$"></t:emailValidator>

</h:inputText>

 

 

 

你可能感兴趣的:(xml,Web,javaee,JSF,sun)