自定义JSF Validator

介绍

在ADF中,我们有很多方式给组件添加验证。

1.直接在组件的validator属性上指定一个manage bean中的method

[java]  view plain copy
  1. public void validate(FacesContext context, UIComponent component,  
  2.                      Object inputValue) {  
  3.     // Add your code here...  
  4. }  

2.通过f:validator标签来指定一个实现了Validator的类,但是却无法灵活的传入参数,例如

[html]  view plain copy
  1. <f:validator validatorId="javax.faces.DoubleRange"/>  

3.自定义一个验证标签,我们可以灵活指定它的各种参数,如错误message,条件等。这也是本文需要描述的内容:自定义一个标签,打成jar包,可以在任何一个ADF项目中引用,可以灵活指定参数等,完成验证某数是否为指定数字的倍数的功能

[html]  view plain copy
  1. <af:inputText label="30的倍数" id="it3" autoSubmit="true"  
  2.                         validator="#{ValidatorBean.validate}">  
  3.             <afcv:validateMultipleNumber multiple="30"  
  4.                                          messageDetailNotMultiple="自定义消息"/>  
  5.             <af:convertNumber/>  
  6.           </af:inputText>  

步骤

1.创建ADF应用,应用目录结构如下



2.编写MultipleNumberValidator类和对应的Tag类逻辑

[java]  view plain copy
  1. package adf.validator;  
  2.   
  3. import javax.el.ValueExpression;  
  4.   
  5. import javax.faces.application.FacesMessage;  
  6. import javax.faces.component.UIComponent;  
  7. import javax.faces.context.FacesContext;  
  8. import javax.faces.validator.Validator;  
  9. import javax.faces.validator.ValidatorException;  
  10.   
  11. import org.apache.myfaces.trinidad.util.MessageFactory;  
  12. import org.apache.myfaces.trinidadinternal.taglib.util.TagUtils;  
  13.   
  14. public class MultipleNumberValidator implements Validator {  
  15.       
  16.     /** 
  17.      * 常量,validator id 
  18.      */  
  19.     public static final String VALIDATOR_ID = "adf.validator.MultipleNumberValidator";  
  20.       
  21.     /** 
  22.      * 对应资源文件中的key 
  23.      */  
  24.     public static final String MULTIPLE_MESSAGE_ID = "adf.validator.MultipleNumberValidator.MULTIPLE";  
  25.       
  26.     /** 
  27.      * 倍数 
  28.      */  
  29.     private ValueExpression _multiple;  
  30.     /** 
  31.      * 验证不通过时的消息 
  32.      */  
  33.     private ValueExpression _messageDetailNotMultiple;  
  34.       
  35.     private Double _multipleValue;  
  36.       
  37.     public MultipleNumberValidator() {  
  38.         super();  
  39.     }  
  40.     /** 
  41.      * 实现验证逻辑 
  42.      * @param context 
  43.      * @param component 
  44.      * @param value 输入值 
  45.      * @throws ValidatorException 
  46.      */  
  47.     @Override  
  48.     public void validate(FacesContext context, UIComponent component,  
  49.                          Object value) throws ValidatorException {  
  50.         if(_multipleValue == null) {  
  51.             _multipleValue = getDoubleValue(context, _multiple);  
  52.         }  
  53.         Double inputValue = null;  
  54.         if (value instanceof java.lang.Number) {  
  55.             inputValue = (((Number)value).doubleValue());  
  56.         } else {  
  57.             inputValue = Double.valueOf(value.toString());  
  58.         }  
  59.         if(_multipleValue != null && inputValue != null) {  
  60.             if(inputValue % _multipleValue != 0) {  
  61.                 throw new ValidatorException(_getMultipleMessage(context,  
  62.                                                                  component, value,  
  63.                                                                  _multipleValue));  
  64.             }  
  65.         }  
  66.     }  
  67.       
  68.     /** 
  69.      * 获取消息资源 
  70.      * @param context 
  71.      * @param component 
  72.      * @param value 
  73.      * @param multiple 
  74.      * @return 
  75.      */  
  76.     private FacesMessage _getMultipleMessage(FacesContext context,  
  77.                                              UIComponent component,  
  78.                                              Object value, Object multiple) {  
  79.         Object message = null;  
  80.         if (_messageDetailNotMultiple != null) {  
  81.             message =  
  82.                     _messageDetailNotMultiple.getValue(context.getELContext());  
  83.         }  
  84.         Object[] params = {value, multiple};  
  85.   
  86.         //系统会根据MULTIPLE_MESSAGE_ID自动找到summary和detail message  
  87.         //detail message的key命名方式是在summary key的命名后面加 "_detail" 后缀  
  88.         return MessageFactory.getMessage(context, MULTIPLE_MESSAGE_ID, message,  
  89.                                          params, component);  
  90.     }  
  91.       
  92.     private Double getDoubleValue(FacesContext context, ValueExpression ve) {  
  93.         if(ve == null) {  
  94.             return null;  
  95.         }  
  96.         Object value = ve.getValue(context.getELContext());  
  97.         if(value != null) {  
  98.             return TagUtils.getDouble(value);          
  99.         }   
  100.         return null;  
  101.     }  
  102.       
  103.     public void setMultiple(ValueExpression _multiple) {  
  104.         this._multiple = _multiple;  
  105.     }  
  106.       
  107.       
  108.     public ValueExpression getMultiple() {  
  109.         return _multiple;  
  110.     }  
  111.   
  112.     public void setMessageDetailNotMultiple(ValueExpression _messageDetailNotMultiple) {  
  113.         this._messageDetailNotMultiple = _messageDetailNotMultiple;  
  114.     }  
  115.   
  116.     public ValueExpression getMessageDetailNotMultiple() {  
  117.         return _messageDetailNotMultiple;  
  118.     }  
  119.   
  120.     public void setMultipleValue(Double _multipleValue) {  
  121.         this._multipleValue = _multipleValue;  
  122.     }  
  123.   
  124.     public Double getMultipleValue() {  
  125.         return _multipleValue;  
  126.     }  
  127. }  
[java]  view plain copy
  1. package adf.validator;  
  2.   
  3. import javax.el.ValueExpression;  
  4.   
  5. import javax.faces.application.Application;  
  6. import javax.faces.context.FacesContext;  
  7. import javax.faces.validator.Validator;  
  8. import javax.faces.webapp.ValidatorELTag;  
  9.   
  10. public class MultipleNumberValidatorTag extends ValidatorELTag {  
  11.       
  12.     private ValueExpression _multiple;  
  13.     private ValueExpression _messageDetailNotMultiple;  
  14.       
  15.     public MultipleNumberValidatorTag() {  
  16.         super();  
  17.     }  
  18.       
  19.     /** 
  20.      *创建Validator实例 
  21.      * @return 
  22.      */  
  23.     @Override  
  24.     protected Validator createValidator() {  
  25.         String validatorId = MultipleNumberValidator.VALIDATOR_ID;  
  26.         //使用这种方式创建validator实例时,必须在faces-config.xml中配置validator  
  27.         //也可以直接使用new关键字创建一个validator实例  
  28.         Application appl = FacesContext.getCurrentInstance().getApplication();  
  29.         MultipleNumberValidator validator = (MultipleNumberValidator)appl.createValidator(validatorId);  
  30.         validator.setMultiple(_multiple);  
  31.         validator.setMessageDetailNotMultiple(_messageDetailNotMultiple);  
  32.         return validator;  
  33.     }  
  34.   
  35.     public void setMultiple(ValueExpression _multiple) {  
  36.         this._multiple = _multiple;  
  37.     }  
  38.   
  39.     public ValueExpression getMultiple() {  
  40.         return _multiple;  
  41.     }  
  42.   
  43.     public void setMessageDetailNotMultiple(ValueExpression _messageDetailNotMultiple) {  
  44.         this._messageDetailNotMultiple = _messageDetailNotMultiple;  
  45.     }  
  46.   
  47.     public ValueExpression getMessageDetailNotMultiple() {  
  48.         return _messageDetailNotMultiple;  
  49.     }  
  50. }  

3.创建tld文件


[html]  view plain copy
  1. <?xml version = '1.0' encoding = 'UTF-8'?>  
  2. <taglib xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"  
  4.         version="2.1" xmlns="http://java.sun.com/xml/ns/javaee">  
  5.   <display-name>ADF Custom Validators</display-name>  
  6.   <tlib-version>1.0</tlib-version>  
  7.   <short-name>afcv</short-name>  
  8.   <uri>http://blog.csdn.net/ygj26/adf/afcv</uri>  
  9.   <tag>  
  10.     <description>倍数验证</description>  
  11.     <name>validateMultipleNumber</name>  
  12.     <tag-class>adf.validator.MultipleNumberValidatorTag</tag-class>  
  13.     <body-content>empty</body-content>  
  14.     <attribute>  
  15.       <name>id</name>  
  16.     </attribute>  
  17.     <attribute>  
  18.       <name>multiple</name>  
  19.       <deferred-value>  
  20.         <type>java.lang.Object</type>  
  21.       </deferred-value>  
  22.     </attribute>  
  23.     <attribute>  
  24.       <name>messageDetailNotMultiple</name>  
  25.       <deferred-value/>  
  26.     </attribute>  
  27.   </tag>  
  28. </taglib>  

4.创建并配置国际化资源文件以及配置validator

英文

[plain]  view plain copy
  1. adf.validator.MultipleNumberValidator.MULTIPLE={0} is not a multiple of {1}.  
  2. adf.validator.MultipleNumberValidator.MULTIPLE_detail={0} is not a multiple of {1}, this value must be a multiple of {1}.  
中文

[plain]  view plain copy
  1. adf.validator.MultipleNumberValidator.MULTIPLE=不正确的倍数  
  2. adf.validator.MultipleNumberValidator.MULTIPLE_detail={0}不是{1}的倍数,该数必须是{1}的倍数  
faces-config.xml配置

[html]  view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee">  
  3.   <application>  
  4.     <default-render-kit-id>oracle.adf.rich</default-render-kit-id>  
  5.     <message-bundle>adf.validator.resources.ValidateMessage</message-bundle>  
  6.   </application>  
  7.   <validator>  
  8.     <validator-id>adf.validator.MultipleNumberValidator</validator-id>  
  9.     <validator-class>adf.validator.MultipleNumberValidator</validator-class>  
  10.   </validator>  
  11. </faces-config>  
5.部署

创建ADF Library部署文件



应用

1.在ADF的Project中引入上面步骤中创建的tag


2.创建测试页面

[html]  view plain copy
  1. <?xml version='1.0' encoding='UTF-8'?>  
  2. <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"  
  3.           xmlns:f="http://java.sun.com/jsf/core"  
  4.           xmlns:h="http://java.sun.com/jsf/html"  
  5.           xmlns:af="http://xmlns.oracle.com/adf/faces/rich"  
  6.           xmlns:afcv="http://blog.csdn.net/ygj26/adf/afcv">  
  7.   <jsp:directive.page contentType="text/html;charset=UTF-8"/>  
  8.   <f:view>  
  9.     <af:document id="d1">  
  10.       <af:form id="f1">  
  11.         <af:messages id="m1" inline="true"/>  
  12.         <af:panelFormLayout id="pfl1">  
  13.           <f:facet name="footer"/>  
  14.           <af:inputText label="10的倍数" id="it1" autoSubmit="true">  
  15.             <afcv:validateMultipleNumber multiple="10"/>  
  16.             <af:convertNumber/>  
  17.           </af:inputText>  
  18.           <af:inputText label="20的倍数" id="it2" autoSubmit="true">  
  19.             <afcv:validateMultipleNumber multiple="#{20}"/>  
  20.             <af:convertNumber/>  
  21.           </af:inputText>  
  22.           <af:inputText label="30的倍数" id="it3" autoSubmit="true"  
  23.                         validator="#{ValidatorBean.validate}">  
  24.             <afcv:validateMultipleNumber multiple="30"  
  25.                                          messageDetailNotMultiple="自定义消息"/>  
  26.             <af:convertNumber/>  
  27.           </af:inputText>  
  28.         </af:panelFormLayout>  
  29.       </af:form>  
  30.     </af:document>  
  31.   </f:view>  
  32. </jsp:root>  

说明

1.现在的验证还不能像ADF已有的验证组件一样在客户端进行验证,而需要submit之后才能触发验证。此功能牵扯到JavaScript的相关内容,如后期有完善功能再写入文章。
2.在某些使用EL表达式设定参数情况下(具体情况不名),就是不能触发验证,debug代码时发现multiple属性为null。如果有大神知情者,还请指教,谢谢!

代码下载

参考文献

Creating Custom JSF Validation

Using the JSF Lifecycle with ADF Faces

转自:http://blog.csdn.net/ygj26/article/details/8314708

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值