JSF2.0中点击<h:commandButton>实现@ViewScoped控制器间对象传递
同@ViewScoped CDI Bean间无重定向传递对象的实现方案
嘿,这个场景我太熟悉了!在JSF 2.0的CDI环境下,要在点击<h:commandButton>后把一个@ViewScoped控制器里的对象传给同作用域的另一个控制器,而且不用重定向,有几种非常实用的方式,我给你拆解清楚:
方法一:CDI直接注入源Bean
因为两个Bean都是**@ViewScoped**(绑定到当前视图),所以可以直接在目标Bean里注入源Bean,这样就能随时访问源Bean里的对象,完全不需要额外的传递逻辑。
源Bean示例:
@Named @ViewScoped // JSF 2.0使用javax.faces.bean.ViewScoped public class SourceBean implements Serializable { private MyDataObject transferObject; // 要传递的自定义对象 // getter和setter public MyDataObject getTransferObject() { return transferObject; } public void setTransferObject(MyDataObject transferObject) { this.transferObject = transferObject; } // 按钮点击触发的方法 public void onButtonClick() { // 初始化或更新要传递的对象 transferObject = new MyDataObject("测试数据内容"); } }
目标Bean示例:
@Named @ViewScoped public class TargetBean implements Serializable { @Inject private SourceBean sourceBean; // 直接注入同视图的源Bean实例 // 在需要的地方获取并处理传递的对象 public void handleReceivedObject() { MyDataObject receivedObj = sourceBean.getTransferObject(); // 这里编写对象处理逻辑 System.out.println("收到的传递数据:" + receivedObj.getContent()); } }
页面上的按钮绑定源Bean的点击方法后,只要目标Bean被访问(比如页面渲染或触发其方法),就能通过注入拿到最新的对象。
方法二:在源Bean中主动获取目标Bean并传递
如果不想用注入,也可以在源Bean的按钮点击方法里,通过JSF上下文手动获取目标Bean的实例,直接把对象设置进去。
源Bean的点击方法修改:
public void onButtonClick() { transferObject = new MyDataObject("测试数据内容"); // 获取当前Faces上下文 FacesContext context = FacesContext.getCurrentInstance(); // 通过EL表达式获取目标Bean实例 TargetBean targetBean = context.getApplication() .evaluateExpressionGet(context, "#{targetBean}", TargetBean.class); // 直接把对象设置到目标Bean targetBean.setReceivedObject(transferObject); }
目标Bean添加对应属性:
@Named @ViewScoped public class TargetBean implements Serializable { private MyDataObject receivedObject; // getter和setter public MyDataObject getReceivedObject() { return receivedObject; } public void setReceivedObject(MyDataObject receivedObject) { this.receivedObject = receivedObject; } }
方法三:页面EL直接传递参数到目标Bean方法
还可以直接在页面的<h:commandButton>里,通过EL表达式把源Bean的对象作为参数,传递给目标Bean的处理方法。
页面代码:
<h:commandButton value="传递对象" action="#{targetBean.processObject(sourceBean.transferObject)}" />
目标Bean的处理方法:
@Named @ViewScoped public class TargetBean implements Serializable { public void processObject(MyDataObject data) { // 直接处理传入的对象 System.out.println("通过参数收到的数据:" + data.getContent()); } }
关键注意事项:
- 两个Bean必须都标记为**@ViewScoped且@Named**,确保它们的生命周期绑定到同一个视图,不会因为请求结束而销毁。
- 要传递的对象必须实现
Serializable接口,因为@ViewScoped会把Bean序列化存储到视图状态中。 - 绝对不要用重定向(比如
return "page?faces-redirect=true"),重定向会创建新的视图,原@ViewScoped Bean的状态会丢失。
内容的提问来源于stack exchange,提问作者B.Bechir
相关产品推荐
相关产品推荐

