最近开始学习JSF基础,发现比较重要的一点,就是如何用编程方式访问托管Bean。看了一些JSF的实例,不过大多都是用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
分享到:
相关推荐
第9章 JSF的托管Bean和国际化课件及源程序 Java国际化实例 I18N_test managedBeanTest
GitHub托管HTML页面,通过GitHub托管自己的项目把自己写的页面让别人访问
本文总结了Fragment在不同情况下的传值方法,包括不同Activity下的Fragment的传值,相同Acitvity托管下不同Fragment的传值。同一界面不同Fragment传值并实时变化的情况。了解了这些,基本上Fragment的通信就不会再有...
对于非托管代码API函数中如何使用委托实现回调方法!
Flux JSF 2 托管 Bean 示例 Flux 可以实现为 JSF 2 Managed bean,它允许用户从他们的 UI 组件调度或管理工作流。 将flux.jar 部署到您的本地maven 存储库 mvn install:install-file -DgroupId=flux -DartifactId=...
堆栈和托管堆的详解堆栈和托管堆的详解堆栈和托管堆的详解堆栈和托管堆的详解堆栈和托管堆的详解
《JavaServer Faces 2.0完全参考手册》对所有jsf功能都进行了解释,包括请求处理生命周期、托管bean、页面导航、组件开发、ajax、验证器、国际化和安全。贯穿全书的专家组意见提供了关于jsf设计的内部信息。 推荐...
安全托管服务MSS介绍PPT 安全托管服务平台培训PPT 安全托管服务需求清单 安全托管服务白皮书 安全托管服务平台工具架构设计 安全托管服务业务设计 Web服务器安全监控防护托管服务主打胶片 华为安全托管服务主打胶片 ...
《JavaServer Faces 2.0完全参考手册》对所有jsf功能都进行了解释,包括请求处理生命周期、托管bean、页面导航、组件开发、ajax、验证器、国际化和安全。贯穿全书的专家组意见提供了关于jsf设计的内部信息。 推荐...
详细介绍了托管代码的机制 方便更深入的了解原理
皮托管使用说明 皮托管使用说明
自托管web服务器(OWIN来将WebApi托管到控制台程序中来运行),不需要用iis等来托管的web服务器,直接双击就可以启动的WebApi服务器。 非常适合开发模拟Web服务器。 参考该代码,也可以自托管到winform程序。 C#, vs...
《在Windows Mobile上使用WINCE自带数据库》中,讲述了在Windows Mobile上使用native code来开发WINCE自带数据库的方法,并给出了例子。现在很多人都使用C#来开发windows mobile上的应用程序,因此,有必要给出这个...
使用readthedocs+github(gitee)+sphinx+reST+typora+webhooks,自动构建托管文档。
一组AMP工具,可让您更轻松地发布和托管AMP页面。___下载.zip
目前.net非常流行,但它是托管的,因此很多时候要与非托管代码通信,本例展示了非托管字符串和托管字符串之间的相互转换
使用和管理过程中普遍存在缺乏专业人员、管理体系不健全、系统建设不规范、系统功能不完备、系统 更新不及时等问题,已经严重制约许多中小银行的发展。然而,中小银行独立建设功能全面的信息系统 和管理规范的IT服务...
使用托管C++粘合C#和C++代码.pdf
为了更好的对代码进行管理,在我们学习当中使用Git仓库对代码托管是非常有必要的,那么今天Four 就给大家带来 如何使用码云对Vs中的代码进行托管