隨筆-9  評論-168  文章-266  trackbacks-0

          最近開始學習JSF基礎,發現比較重要的一點,就是如何用編程方式訪問托管Bean??戳艘恍㎎SF的實例,不過大多都是用JSF1.1來實現的。雖然在JSF1.2的環境中也可以很好運行,但是在編譯的時候會看到降級的消息。這里找了一些資料總結一下JSF1.1和JSF1.2訪問托管Bean的方法。

          一、從JSF頁面傳遞參數給托管Bean
          雖然利用h:commandLink 和h:commandButton組件,可以通過action和actionListener來觸發托管Bean中的方法,但是不能向這些方法中傳遞參數。對于動態傳遞參數,不是不可以實現,這點可以通過使用f:attribute來實現。而且f:attribute也可以很好的和actionListener聯合使用。
          例子:



          <h:commandLink actionListener="#{myBean.action}">
                  
          <f:attribute name="attrname1" value="attrvalue1" />
                  
          <f:attribute name="attrname2" value="attrvalue2" />
                  ...   
                  
          <h:outputText value="Click here" />
              
          </h:commandLink>
              
              
          <h:commandButton value="Press here" actionListener="#{myBean.action}">
                  
          <f:attribute name="attrname1" value="attrvalue1" />
                  
          <f:attribute name="attrname2" value="attrvalue2" />
                  ...
              
          </h:commandButton>

          這些屬性可以通過父組件的getAttributes()方法取到,父組件可以通過傳遞給actionListener的ActionEvent實例取到



          public void action(ActionEvent event) 
              
          {   
                  String attrvalue1 
          = (String) event.getComponent().getAttributes().get("attrname1");
                  String attrvalue2 
          = (String) event.getComponent().getAttributes().get("attrname2");
                  ...
              }

          變量attrvalue1和attrvalue2包含從f:attribute set進來的值。
          另一個欠文雅的方式就是通過f:param組件來傳值,這個只是對h:commandLink起效。



          <h:commandLink action="#{myBean.action}">
                  
          <f:param name="paramname1" value="paramvalue1" />
                  
          <f:param name="paramname2" value="paramvalue2" />
                  ...
                  
          <h:outputText value="Click here" />
              
          </h:commandLink>

          這些參數可以通過FacesContext的getRequestParameterMap()方法取到。通過下面的方法,可以獲取任何寫在command塊中f:param的值。



          public static String getFacesParamValue(String name) 
              
          {   
                  
          return (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(name);
              }

          上面的方法可以用在任何Bean的方法中。舉例



          public void action() 
              
          {   
                  String paramvalue1 
          = getFacesParamValue("paramname1");   
                  String paramvalue2 
          = getFacesParamValue("paramname2");   
                  ...
              }

          變量paramvalue1和paramvalue2包含從f:param set進來的值。
          不過要注意,屬性的名字要唯一,而且不能用其他組件的屬性名,比如:"id", "name", "value","binding", "rendered",等。

          二、從JSF頁面傳遞組件屬性到托管Bean
          f:attribute組件也可以用來訪問,任何綁定在托管Bean的UI組件的屬性。這些屬性值可以通過父組件的getAttributes()來獲得。因為不能以方法參數的方式傳值給托管Bean綁定的UI組件的getter和setter方法,這時f:attribute就會非常有用。這里有個UI組件綁定到托管Bean的基礎例子



          <h:outputText binding="#{myBean.myText}" value="#{myBean.myTextValue}">
                  
          <f:attribute name="attributename" value="attributevalue" />
              
          </h:outputText>

           



          托管Bean代碼:

          import javax.faces.component.html.HtmlOutputText;
          public class MyBean 
          {   
              
          private HtmlOutputText myText; 
              
              
          public HtmlOutputText getMyText() 
              
          {   
                  
          return myText;  
              }
             
              
              
          public String getMyTextValue() 
              
          {       
                  
          return (String) myText.getAttributes().get("attributename");   
              }

              
              
          public void setMyText(HtmlOutputText myText) 
              
          {       
                  
          this.myText = myText;
              }

          }

          三、在請求之間傳遞對象(Passing objects from request to request)
          如果有一個request范圍內的托管Bean,在下一個請求中想要重用這個bean的屬性,參數,或者對象,但是不想一遍又一遍的初始化這個Bean??梢杂胔:inputhidden來解決這個問題。這里有個簡單的例子:



          <h:form>   
                  ...
                  
          <h:inputHidden value="#{myBean.value}" />
                ...
              
          </h:form>

          另一種方法就是用SessionMap來保存那些需要保存在session中的值。



          public class MyBean 
          {   
              
          public Object getMyValue() 
              
          {       
                  
          return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("MyBeanMyValue"); 
              }
             
              
              
          public void setMyValue(Object myValue) 
              
          {       
                  FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(
          "MyBeanMyValue", myValue);
              }
            
                
              
          // This might be useful.   
              private void resetSessionValue(Object myKey) 
              
          {       
                  FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(myKey);
              }

          }

          四、在托管Bean之間通信
          實踐時會有多個托管Bean。如果設計需要,可以利用getSessionMap()在托管Bean之間通信。
          一個例子,有兩個托管Bean:



          <managed-bean>
                  
          <managed-bean-name>myBean1</managed-bean-name>
                  
          <managed-bean-class>mypackage.MyBean1</managed-bean-class>
                  
          <managed-bean-scope>request</managed-bean-scope>
              
          </managed-bean>
              
          <managed-bean>
                  
          <managed-bean-name>myBean2</managed-bean-name>
                  
          <managed-bean-class>mypackage.MyBean2</managed-bean-class>
                  
          <managed-bean-scope>session</managed-bean-scope>
              
          </managed-bean>

          托管Bean myBean1和myBean2是支撐Bean MyBean1.java和MyBean2.java的實例,它們可以通過JSF頁面來訪問。不管它們的managed-bean-scope是request還是session。如果managed-bean-scope被設置成session,在整個session范圍內可以使用同一個Bean的實例;如果managed-bean-scope被設置成request,那么每個request(form action)每次會創建一個Bean的實例。

          用下面的方法,可以為每個托管Bean set和get static的參數??梢园阉鼘懗蓀rotected方法,放在一個超類中,讓每個托管Bean繼承,這會非常有用,或者寫入一個Util類中,自己選擇。

           



          public class MySuperBean 
          {   
              
          protected static Object getSessionValue(Object myKey) 
              
          {       
                  
          return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(myKey);
              }
             
              
              
          protected static void setSessionValue(Object myKey, Object myValue) 
              
          {       
                  FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(myKey, myValue);
              }

          }


          public class MyBean1 extends MySuperBean 
          {   
              
          public void myMethod() 
              
          {       
                  String myValue 
          = "value1";       
                  setSessionValue(
          "MyBean1MyValue", myValue);
                  ...   
              }

          }

          public class MyBean2 extends MySuperBean 
          {   
              
          public void myMethod() 
              
          {       
                  String myValue 
          = (String) getSessionValue("MyBean1MyValue");
                  ...   
              }

          }

          五、在托管Bean中訪問另一個托管Bean
          如果有很多托管Bean,想要從其中一個托管Bean訪問其他的托管Bean,這里有六中方法。
          可以使用:
            1)getVariableResolver
            2)createValueBinding
            3)getELResolver (since JSF 1.2)
            4)createValueExpression (since JSF 1.2)
            5)getRequestMap
            6)getSessionMap.
          舉例:假設有兩個托管Bean



          <managed-bean>
              
          <managed-bean-name>myBean1</managed-bean-name>
              
          <managed-bean-class>mypackage.MyBean1</managed-bean-class>
              
          <managed-bean-scope>request</managed-bean-scope>
          </managed-bean>
          <managed-bean>
          <managed-bean-name>myBean2</managed-bean-name>
              
          <managed-bean-class>mypackage.MyBean2</managed-bean-class>
              
          <managed-bean-scope>session</managed-bean-scope>
          </managed-bean>

          托管Bean myBean1和myBean2是支撐Bean MyBean1.java和MyBean2.java的實例,它們可以通過JSF頁面來訪問。不管它們的managed-bean-scope是request還是session。
          只是要注意的是,getRequestMap在托管Bean被設置成request的時候使用,getSessionMap在托管Bean被設置成session的時候使用。



          <h:form>   
              
          <h:commandButton action="#{myBean1.action1}" value="action1" />
              
          <h:commandButton action="#{myBean1.action2}" value="action2" />
              
          <h:commandButton action="#{myBean1.action3}" value="action3" />
              
          <h:commandButton action="#{myBean1.action4}" value="action4" />
              
          <h:commandButton action="#{myBean1.action5}" value="action5" />
              
          <h:commandButton action="#{myBean1.action6}" value="action6" />
              
          <h:outputText binding="#{myBean2.text}" />
          </h:form>

          MyBean1.java:

          package mypackage;
          import javax.faces.context.FacesContext;
          public class MyBean1 
          {    
              
          // Using VariableResolver. NOTE: this is deprecated since JSF 1.2!   
              public void action1() 
              
          {       
                  FacesContext context 
          = FacesContext.getCurrentInstance();       
                  MyBean2 myBean2 
          = (MyBean2) context.getApplication().getVariableResolver().resolveVariable(context, "myBean2");
                  myBean2.getText().setValue(
          "action1");   
              }
             
              
              
          // Using ValueBinding. NOTE: this is deprecated since JSF 1.2!   
              public void action2() 
              
          {       
                  FacesContext context 
          = FacesContext.getCurrentInstance(); 
                  MyBean2 myBean2 
          = (MyBean2) context.getApplication().createValueBinding("#{myBean2}").getValue(context);       
                  myBean2.getText().setValue(
          "action2");   
              }
             
              
              
          // Using ELResolver. NOTE: this is implemented since JSF 1.2!  
              public void action3() 
              
          {       
                  FacesContext context 
          = FacesContext.getCurrentInstance();
                  MyBean2 myBean2 
          = (MyBean2) context.getELContext().getELResolver().getValue(context.getELContext(), null"myBean2");
                  myBean2.getText().setValue(
          "action3");
              }
             
              
              
          // Using ValueExpression. NOTE: this is implemented since JSF 1.2!   
              public void action4() 
              
          {       
                  FacesContext context 
          = FacesContext.getCurrentInstance();
                  MyBean2 myBean2 
          = (MyBean2) context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), "#{myBean2}", MyBean2.class).getValue(context.getELContext());
                  myBean2.getText().setValue(
          "action4");   
              }
            
              
              
          // Using RequestMap. NOTE: myBean2 should be request scoped!   
              public void action5() 
              
          {       
                  Object object 
          = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("myBean2");
                  
          // This only works if myBean2 is request scoped.       
                  if (object != null
                  
          {           
                      MyBean2 myBean2 
          = (MyBean2) object;
                      myBean2.getText().setValue(
          "action5");       
                  }
             
              }
             
              
              
          // Using SessionMap. NOTE: myBean2 should be session scoped!   
              public void action6() 
              
          {       
                  Object object 
          =  FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("myBean2");
                  
          // This only works if myBean2 is session scoped.       
                  if (object != null
                  
          {         
                      MyBean2 myBean2 
          = (MyBean2) object;
                      myBean2.getText().setValue(
          "action6"); 
                  }
             
              }


          }


          MyBean2.java:

          package mypackage;
          import javax.faces.component.html.HtmlOutputText;
          public class MyBean2 
          {   
              
          private HtmlOutputText text;   
              
              
          public HtmlOutputText getText() 
              
          {       
                  
          return text;   
              }
             
              
              
          public void setText(HtmlOutputText text) 
              
          {       
                  
          this.text = text;   
              }

          }
          posted on 2008-04-16 15:27 紫蝶∏飛揚↗ 閱讀(4631) 評論(4)  編輯  收藏 所屬分類: JSF

          評論:
          # re: 托管 Bean 頁面傳值的使用方法和技巧[未登錄] 2008-11-19 12:16 | p
          好東西,我正在學呢  回復  更多評論
            
          # re: 托管 Bean 頁面傳值的使用方法和技巧 2008-11-28 10:06 | 冷風寒笑
          好文~~  回復  更多評論
            
          # re: 托管 Bean 頁面傳值的使用方法和技巧 2008-12-18 09:51 | jsf fans
          very good!  回復  更多評論
            
          # re: 托管 Bean 頁面傳值的使用方法和技巧 2012-12-22 09:34 | 李莫愁
          不管怎么上,支持一下  回復  更多評論
            
          主站蜘蛛池模板: 苗栗县| 那坡县| 嫩江县| 集安市| 婺源县| 玛纳斯县| 民权县| 哈巴河县| 宜阳县| 安平县| 新密市| 城固县| 东兴市| 鄂托克旗| 水城县| 昌图县| 团风县| 平遥县| 沁水县| 滁州市| 青龙| 高青县| 甘南县| 行唐县| 高阳县| 白朗县| 新丰县| 鄄城县| 黑山县| 裕民县| 武汉市| 永泰县| 大新县| 长岭县| 收藏| 怀宁县| 临洮县| 永吉县| 孟州市| 潞西市| 朝阳区|