为了避免使用Session的一些弊病,除了保存用户信息等公用数据的BackingBean外,对于业务逻辑处理最好使用request 类型的BackingBean。 因此,以下的相关说明都是以request 类型的BackingBean为基础的。
1、 具有导航规则的两个JSF页面之间交互,如果两个页面使用同一个BackingBean的,只需要在页面中加入<x:saveState>就可以,如下:
本次request的number1的当前值会被自动保存,在紧接着的一次request中会被自动恢复,于是就达到了两个页面间参数的传递。当然也可以直接保存整个Bean的信息,达到页面参数传递的作用,如:
注:使用UISaveState组件必须安装Myface,saveState保存的对象类必须实现serializable接口,saveState保存的对象的生存期介于request和session之间。
2、对于使用a.jsp?param1形式传递参数的页面,在backingBean中采用读取requestParameter参数的方式获得。
HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
String value = request .getParameter(parameterName);
值得注意的是,在目标页面中上获得的Parameter很容易丢失,特别在backingBean与该页面交互的Aciton操作,因此可以将其作为变量并结合saveState保存起来(或者页面放置InputHidden,并与Bean中的UIInput绑定起来,获得Parameter时候将其保存在UIInput的value中;也可利用客户端javascript来管理)。
以上是种解决方法,不过我们想到是否能在JSF页面利用inputText(或InputHidden)和RequestParameterMap访问并保存参数呢?这样的好处是将参数置于form中的input上,由于我们设置了forceId="true",因此,再次提交该页面的时候我们又可以用param['parameterName']访问该参数,服务端也可以用getParameter取得参数。
但是因为RequestParameterMap是只读的,对其的Set写入操作是不允许的,因此上面的代码在验证阶段会提示错误。但是我们可以经过变通将其进行复制到一个可读写的Map中:
public Map getParam() ... {
if (_requestParameterMap.isEmpty())
_requestParameterMap.putAll(FacesContext.getCurrentInstance().getExternalContext()
.getRequestParameterMap());
return _requestParameterMap;
}
将该代码所在的backingBean注册为requestParam,然后就可以在页面上调用了:
或者
< h:inputText id ="parameterName" forceId ="true" value ="#{requestParam.param.parameterName}" />
还有一种方法是借助在config.xml文件中配置进行参数传递:
< managed-bean-name > customer </ managed-bean-name >
< managed-bean-class > foo.Customer </ managed-bean-class >
< managed-bean-scope > request </ managed-bean-scope >
< managed-property >
< property-name > userId </ property-name >
< property-class > java.lang.String </ property-class >
< value > #{param.userid} </ value >
</ managed-property >
</ managed-bean >
通过#{param.userid}就将参数传递并保存在了Bean的变量userId中,完全通过配置达到了目的,也是一种不错的方法。
3、 对于需要从一个bean向其他bean传递参数的,如果前面两种方式都无法实现,请采用<x: updateActionListener >作为参数传递。 代码示例:
< x:updateActionListener property ="#{letterOutBean.selectedLetterId}" value ="#{letter.id}" />
</ h:commandLink >
注意:x:updateActionListener必须放在动作里面才能使用,例如上面代码或者commandButton
4、获得同一页面不同BackingBean的值,可以使用EL表达式和getValueBinding函数结合的方式:
ShoppingCartBean cart = (ShoppingCartBean) getValueBinding( " #{shoppingCartBean} " ).getValue(facesContext);
或者直接找组件,然后取得值
原文:转载,根据本人经验作了较大修订。