最近開始學習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。可以用h: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的參數。可以把它寫成protected方法,放在一個超類中,讓每個托管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
紫蝶∏飛揚↗ 閱讀(4625)
評論(4) 編輯 收藏 所屬分類:
JSF