隨筆-348  評(píng)論-598  文章-0  trackbacks-0
          UI控件、轉(zhuǎn)換器和驗(yàn)證器實(shí)現(xiàn)了StateHolder接口表示組件具有了狀態(tài),可以保存一些組件自身的屬性。

          下面我們來(lái)看一個(gè)簡(jiǎn)單的例子。
          這是一個(gè)正則表達(dá)式驗(yàn)證器的例子:
          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;
              
              
          /**
               * 出錯(cuò)時(shí)的提示內(nèi)容名稱,例如郵編
               
          */

              
          private String errorPatternDisplayName = null;
              
              
          /**
               * 獲得樣式的配置文件
               
          */

              
          private static final ResourceBundle bundle = ResourceBundle.getBundle(Const.BUNDLE_ROOT + ".RegexPattern");
              
              
          /**
               * 資源配置文件中對(duì)應(yīng)的樣式名稱
               
          */

              
          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標(biāo)簽:
          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;
              }


          }
          這個(gè)驗(yàn)證標(biāo)簽接受一個(gè)名稱作為參數(shù),通過(guò)此名稱可以從相關(guān)配置文件中查找到相應(yīng)的正則表達(dá)式和其他一些配置信息。

          但如果你使用這個(gè)驗(yàn)證器,你會(huì)發(fā)現(xiàn),每次都正確調(diào)用了,也都將參數(shù)傳進(jìn)去了,但是在調(diào)用validate方法的時(shí)候卻發(fā)現(xiàn)自定義的幾個(gè)驗(yàn)證器的屬性的值都為null。這是為什么呢?
          因?yàn)槲覀兊谝淮握{(diào)用的時(shí)候初始化了一下,參數(shù)都進(jìn)去了,驗(yàn)證器也被實(shí)例化了,但是這個(gè)驗(yàn)證器卻是瞬時(shí)狀態(tài)的,剛被頁(yè)面實(shí)例化好就被釋放了。所以提交表單驗(yàn)證的時(shí)候會(huì)重新被初始化,但這時(shí)只是調(diào)用了默認(rèn)構(gòu)造函數(shù),沒(méi)有將我們的正則表達(dá)式樣式作為參數(shù)傳進(jìn)去。

          如何保存驗(yàn)證器之前的狀態(tài)呢?或者說(shuō)如何讓驗(yàn)證器不是瞬時(shí)狀態(tài)呢。
          這就需要實(shí)現(xiàn)StateHolder接口,并且實(shí)現(xiàn)幾個(gè)方法,讓JSF知道,這個(gè)驗(yàn)證器有自己的狀態(tài)需要保存。
          新的代碼:
          public class RegexValidator implements Validator, StateHolder
          {
              
          /**
               * 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;
              
              
          /**
               * 出錯(cuò)時(shí)的提示內(nèi)容名稱,例如郵編
               
          */

              
          private String errorPatternDisplayName = null;
              
              
          /**
               * 獲得樣式的配置文件
               
          */

              
          private static final ResourceBundle bundle = ResourceBundle.getBundle(Const.BUNDLE_ROOT + ".RegexPattern");
              
              
          /**
               * 資源配置文件中對(duì)應(yīng)的樣式名稱
               
          */

              
          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");
               
              }


              
          private boolean transientValue = false;
              
              
          public void setTransient(boolean transientValue)
              
          {
                  
          this.transientValue = transientValue;
              }

              
              
          public boolean isTransient()
              
          {
                  
          return this.transientValue;
              }


              
          public void restoreState(FacesContext context, Object state)
              
          {
                  Object values[] 
          = (Object[]) state;
                  formatPatterns 
          = (String) values[0];
                  errorPatternDisplayName 
          = (String) values[1];
              }


              
          public Object saveState(FacesContext context)
              
          {
                  Object[] values 
          = new Object[2];
                  values[
          0= formatPatterns;
                  values[
          1= errorPatternDisplayName;
                  
          return values;
              }


          }

          實(shí)現(xiàn)setTransient和isTransient兩個(gè)方法是為了標(biāo)明這個(gè)驗(yàn)證器不是瞬時(shí)狀態(tài),需要返回一個(gè)false。
          實(shí)現(xiàn)saveState和restoreState兩個(gè)方法是為了保存和還原狀態(tài),大家可以看下代碼,saveState保存了當(dāng)前驗(yàn)證器需要的幾個(gè)屬性參數(shù),而restoreState將這些參數(shù)重新還原給了驗(yàn)證器,這樣,我們使用新代碼做驗(yàn)證的時(shí)候,就會(huì)發(fā)現(xiàn)它起作用了。

          ---------------------------------------------------------
          專注移動(dòng)開(kāi)發(fā)

          Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian
          posted on 2008-11-05 14:15 TiGERTiAN 閱讀(1662) 評(píng)論(2)  編輯  收藏 所屬分類(lèi): JavaJSF

          評(píng)論:
          # re: JSF(Java Server Faces)的StateHolder的作用和使用方法 2008-11-06 01:05 | Lf0x
          暫存,待看,O(∩_∩)O哈哈~  回復(fù)  更多評(píng)論
            
          # re: JSF(Java Server Faces)的StateHolder的作用和使用方法 2008-11-06 09:18 | TiGERTiAN
          @Lf0x
          呵呵,自己總結(jié)的,見(jiàn)笑了。  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 虹口区| 扎兰屯市| 祁阳县| 南岸区| 黄山市| 德格县| 兰州市| 株洲市| 曲靖市| 沅江市| 手机| 凤台县| 太康县| 若尔盖县| 塔城市| 名山县| 嘉鱼县| 大悟县| 广丰县| 太仓市| 林西县| 沭阳县| 涿鹿县| 贵南县| 和平县| 固镇县| 麟游县| 沅江市| 木里| 万宁市| 运城市| 兴城市| 柯坪县| 北票市| 三门峡市| 综艺| 松原市| 北宁市| 古蔺县| 荥经县| 永善县|