UI控件、转换器和验证器实现了StateHolder接口表示组件具有了状态,可以保存一些组件自身的属性。
下面我们来看一个简单的例子。
这是一个正则表达式验证器的例子:
public
class
RegexValidator
implements
Validator
{
/**
* The message identifier of the Message to be created if
* the validation fails.
*/
public
static
final
String REGEX_INVALID_MESSAGE_ID
=
"
validator.Regex_Invalid
"
;
private
String formatPatterns
=
null
;
/**
* 出错时的提示内容名称,例如邮编
*/
private
String errorPatternDisplayName
=
null
;
/**
* 获得样式的配置文件
*/
private
static
final
ResourceBundle bundle
=
ResourceBundle.getBundle(Const.BUNDLE_ROOT
+
"
.RegexPattern
"
);
/**
* 资源配置文件中对应的样式名称
*/
private
String formatPatternName
=
null
;
public
RegexValidator()
{
super
();
}
public
RegexValidator(String formatPatternName)
{
setFormatPatternName(formatPatternName);
}
public
void
validate(FacesContext context, UIComponent component, Object toValidate)
throws
ValidatorException
{
if
(context
==
null
||
component
==
null
)
throw
new
NullPointerException();
if
(
!
(component
instanceof
UIOutput))
return
;
if
(formatPatterns
==
null
||
formatPatterns.length()
==
0
||
null
==
toValidate)
return
;
String value
=
toValidate.toString();
Pattern p
=
Pattern.compile(
this
.formatPatterns);
Matcher m
=
p.matcher(value);
boolean
b
=
m.matches();
if
(
!
b)
{
FacesMessage errMsg
=
MessageFactory.getMessage(context,
this
.REGEX_INVALID_MESSAGE_ID,
new
Object[]
{errorPatternDisplayName}
);
throw
new
ValidatorException(errMsg);
}
}
public
String getFormatPatternName()
{
return
formatPatternName;
}
public
void
setFormatPatternName(String formatPatternName)
{
this
.formatPatternName
=
formatPatternName;
this
.errorPatternDisplayName
=
bundle.getString(formatPatternName);
this
.formatPatterns
=
bundle.getString(formatPatternName
+
"
_patterns
"
);
}
}
它的Tag标签:
public
class
RegexValidatorTag
extends
ValidatorELTag
{
private
String formatPatternName;
public
RegexValidatorTag()
{
super
();
}
/*
(non-Javadoc)
* @see javax.faces.webapp.ValidatorELTag#createValidator()
*/
@Override
protected
Validator createValidator()
throws
JspException
{
RegexValidator v
=
new
RegexValidator();;
v.setFormatPatternName(formatPatternName);
return
v;
}
public
String getFormatPatternName()
{
return
formatPatternName;
}
public
void
setFormatPatternName(String formatPatternName)
{
this
.formatPatternName
=
formatPatternName;
}
}
这个验证标签接受一个名称作为参数,通过此名称可以从相关配置文件中查找到相应的正则表达式和其他一些配置信息。
但如果你使用这个验证器,你会发现,每次都正确调用了,也都将参数传进去了,但是在调用validate方法的时候却发现自定义的几个验证器的属性的值都为null.这是为什么呢?
因为我们第一次调用的时候初始化了一下,参数都进去了,验证器也被实例化了,但是这个验证器却是瞬时状态的,刚被页面实例化好就被释放了。所以提交表单验证的时候会重新被初始化,但这时只是调用了默认构造函数,没有将我们的正则表达式样式作为参数传进去。