标准数据转换
<h:inputText id="date" value="#{conversionDemo.date}"> <f:convertDateTime pattern="yyyy/MM/dd"/> </h:inputText> |
对应ManagedBean的如下代码
public class ConversionDemo { private Date date = new Date(); public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } } |
标准数据转换包括number和DateTime,DateTime已经演示了,下面试number:
<h:inputText id="amount" value="#{conversionDemo.amount}"> <f:convertNumber minFractionDigits="2"/> </h:inputText> |
这是Core JSF提供的列表:
这是Core JSF提供的列表:
这是Core JSF提供的列表:
这是Core JSF提供的列表:
|
|
数据转换错误信息的显示和改变
<h:inputText id="date" value="#{conversionDemo.date}"> <f:convertDateTime pattern="yyyy/MM/dd"/> </h:inputText> <h:message for="date" style="color:#ff0000"/> |
注意加重的部分,必须相同。
如果需要修改输出信息则应把对应的信息写在properties文件中:
<f:loadBundle basename="resources.application" var="bundle"/> |
这个表示绑定一个properties文件:classpath下的resources下的application.properties(或者你喜欢的位置和名字),你可以修改这个文件,把错误信息写在这里。例如DateTimeConvertor:
javax.faces.convert.DateTimeConverter.CONVERSION=请按照正确的日期格式输入 |
这些名字不能错,Core JSF上写的就有问题,也许是JSF版本不同吧。这些名字定义在转换类中,例如:
private static final String CONVERSION_MESSAGE_ID = "javax.faces.convert.ByteConverter.CONVERSION"; |
记不住就查源代码,规律是javax.faces.convert.类型Converter.CONVERSION,“类型”指的是转换类型,例如Integer,Double。
自定义转换
自定义转换
自定义转换
自定义转换
可以自定义类型转换,实现import javax.faces.convert.Converter;接口即可,如果转换失败抛出import javax.faces.convert.ConverterException;异常。Converter接口包括两个方法:
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) throws ConverterException ; public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) throws ConverterException ; |
前一个表示将Form中的表单转换为某个对象,后者表示将某个对象转换为显示在表单上的字符。这种实现都不复杂,可以参考myfaces的源代码,需要注意的是,如果转换失败抛出一个ConverterException异常,需要根据情况传入一个错误字符串,该字符串可以生成也可以从绑定文件中取,javax.faces.convet包里有一个_MessageUtils类,可惜是包级私有的,我们抄袭一个出来就可以用了。
try{ return (java.util.Date)Date.valueOf(value);//类型转换 } catch(IllegalArgumentException e) { //MessageUitl就是抄袭的那个类 throw new ConverterException(MessageUtil.getErrorMessage(facesContext, CONVERSION_MESSAGE_ID,//常量,属性文件中错误信息的”key” new Object[]{value,uiComponent.getId()}), e); } |
关于转换,org.apache.myfaces.convert.ConvertUtils提供了一些常用的转换方法,相信spring也提供了相当多的转换,都可以拿来主义。
标准验证的格式
<h:inputText id="card" value="#{conversionDemo.card}" required="true"> <f:validateLength maximum="18"/> </h:inputText> |
上述代码表示card字段是必须填写的,并且最大长度18字符(unicode)。
<h:inputText id="card" value="#{conversionDemo.card}" required="true"> <f:validateLength maximum="18"/> </h:inputText> <h:message for="card" style="color:#ff0000"/> |
如果输入错误,会出现提示,提示内容写在配置文件中:
javax.faces.validator.LengthValidator.MAXIMUM=超出最大长度,应小于等于{0}。 javax.faces.component.UIInput.REQUIRED=该值是必须的。 |
注意:{0}表示一种参数,还记得new Object[]{value,uiComponent.getId()})吗?就是这个数组的元素。
标准验证
常见的标准验证有:
|
唯一需要注意的是这些验证的MessageID,例如LongRangeValidator:
public static final String MAXIMUM_MESSAGE_ID = "javax.faces.validator.LongRangeValidator.MAXIMUM"; public static final String MINIMUM_MESSAGE_ID = "javax.faces.validator.LongRangeValidator.MINIMUM"; public static final String TYPE_MESSAGE_ID = "javax.faces.validator.LongRangeValidator.TYPE"; public static final String VALIDATOR_ID = "javax.faces.LongRange"; |
其他的需要看代码了。
修改验证信息
Myfaces扩展验证
MyFaces提供了许多扩展,其中就包括验证:
<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="x" %> |
下面的例子表示验证两个表单字段是否相同,经常用在重复输入密码或email的情况下:
<h:outputText value="#{bundle['demo.email']}"/> <h:inputText id="email" value="#{conversionDemo.email}" required="true"> <f:validator validatorId="org.apache.myfaces.validator.Email"/> <v:commonsValidator type="email" arg="#{bundle['demo.email']}"/> </h:inputText> <x:message for="email" style="color:#ff0000"/> <h:panelGroup/>
<h:outputText value="#{bundle['demo.confirmEmail']}"/> <h:inputText id="confirmEmail" required="true"> <x:validateEqual for="email"/> </h:inputText> <x:message for="confirmEmail" style="color:#ff0000"/> |
下面是相关的错误提示信息:
org.apache.myfaces.Equal.INVALID=您输入的{0}必须等于{1} |
Myfaces的扩展都在org.apache.myfaces.custom下面,慢慢研究吧。
自定义验证
自定义验证需要实现javax.faces.validator.Validator接口,该接口只有一个方法:
public void validate(FacesContext ctx, UIComponent uic, Object value) |
你需要验证的就是这个value,下面是一个例子:
public class IPValidator implements Validator {
public static final String MESSAGE_ID = "net.chinasam.samples.jsf.IPValidator.IP"; public static final String VALIDATOR_ID = "net.chinasam.samples.jsf.IPValidator"; public void validate(FacesContext ctx, UIComponent uic, Object value) throws ValidatorException { if (ctx == null) throw new NullPointerException("facesContext"); if (uic == null) throw new NullPointerException("uiComponent"); if(value == null) { return; } int length = value instanceof String ? ((String)value).length() : value.toString().length(); Object []args = new Object[]{value, uic.getId()}; if(length < 7 || length > 15) { throw new ValidatorException(MessageUtil.getErrorMessage(ctx, MESSAGE_ID, args)); } String ip = value.toString(); String []subIp = ip.split("//."); if(subIp.length!= 4) { throw new ValidatorException(MessageUtil.getErrorMessage(ctx, MESSAGE_ID, args)); } for(int i = 0; i < 4; i++) { int sIp = Integer.valueOf(subIp[i]).intValue(); if(sIp > 255 || sIp < 0) { throw new ValidatorException(MessageUtil.getErrorMessage(ctx, MESSAGE_ID, args)); }}}} |
使用客户端验证
以上验证都是在服务器端的,也可以实现客户端,只是JSF目前没有这个功能,我们可以使用corejsf.com提供的一个taglib也可以使用Struts的,介绍一下corejsf.com的,这个包不好找,我是用的appfuse自带的那个,它也自带一个Validator-rules.xml,复制corejsf-validator.jar,commons-validator.jar 和jakarta-oro.jar 到WEB-INF/lib下,复制Validator-rules.xml到WEB-INF下。
JSP页面下添加:
<%@ taglib uri="http://corejsf.com/validator" prefix="v" %> |
需要客户端验证的form修改为:
<h:form onsubmit="return validateUserForm(this)"> |
页面最后加入:
<v:validatorScript functionName="validateUserForm"/> </body> |
例如,对email进行验证:
<h:inputText id="email" value="#{conversionDemo.email}" required="true"> <f:validator validatorId="org.apache.myfaces.validator.Email"/> <v:commonsValidator type="email" arg="随便填?"/> </h:inputText> |
粗体部分表示客户端验证。如果验证required属性,则:
<v:commonsValidator type="required" arg=""/> |
我还不会验证dateL,另外,如果在弹出对话框中输入中文也是个问题。
还有,validate-rules.xml定义了errorMessage的key:
<validator name="float" classname="org.apache.commons.validator.GenericValidator" method="isDouble" methodParams="double" depends="" msg="errors.float" jsFunctionName="FloatValidations"> |
关于这个第三方taglib,俺还没有研究透,回头再说吧。