在 @ViewScoped bean 之间传递对象而不使用 GET 参数

Posted

技术标签:

【中文标题】在 @ViewScoped bean 之间传递对象而不使用 GET 参数【英文标题】:Pass an object between @ViewScoped beans without using GET params 【发布时间】:2014-10-30 21:52:45 【问题描述】:

我有一个browse.xhtml,我在其中浏览cars 的列表,当按下“查看更多”按钮时,我想在details.xhtml 中查看汽车的详细信息。它们的支持 bean 是@ViewScoped,分别称为BrowseBeanDetailsBean

现在,我不希望用户/客户端在 URL 中看到汽车 ID,因此我想避免使用 GET 参数,如 here 和 here 所示。

有什么方法可以实现吗?我将 Mojarra 2.2.8 与 PrimeFaces 5 和 OmniFaces 1.8.1 一起使用。

【问题讨论】:

【参考方案1】:

取决于您是发送重定向还是仅仅导航。

如果您要发送重定向,请将其放入 flash 范围内:

Faces.setFlashAttribute("car", car);

这在下一个 bean 的 @PostConstruct 中可用:

Car car = Faces.getFlashAttribute("car");

或者,如果您只是导航,则将其放在请求范围内:

Faces.setRequestAttribute("car", car);

这在下一个 bean 的 @PostConstruct 中可用:

Car car = Faces.getRequestAttribute("car");

另见:

Injecting one view scoped bean in another view scoped bean causes it to be recreated How to pass objects from one page to another page in JSF without writing a converter

请注意,我假设您非常清楚拥有两个完全独立的视图的设计选择,如果没有另一个视图,它们就不能存在(幂等),而不是拥有例如具有条件渲染内容的单个视图。并且您已经知道视图在实际被幂等请求时应该如何表现(即通过书签、共享链接、搜索机器人等)。如果没有,那么我强烈建议您仔细阅读这个问题的答案:How to navigate in JSF? How to make URL reflect current page (and not previous one)。


更新:如果您不使用 OmniFaces,请分别使用以下内容:

FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car", car);
Car car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("car", car);
Car car = (Car) FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("car");

【讨论】:

感谢您的回复,但我在Faces.setFlashAttribute("car", car); 上收到了ClassNotFoundException,here 是跟踪。 omn​​ifaces 库范围设置为compile,对吗? (尝试将其设置为运行时,我又遇到了同样的异常) 运行时类路径中缺少 OmniFaces。显然 Maven 构建以某种方式失败了。 OmniFaces 必须(与 PrimeFaces 完全一样)最终位于构建的 /WEB-INF/lib 文件夹中。默认范围(编译)应该可以正常工作。 我试过mvn compile,它已经成功完成了。这是我现在的范围。我什至在pom.xml 上明确声明了它,但我仍然遇到异常。我应该下载 jar 并将其添加到 WEB-INF/lib 文件夹中,就像 Primefaces 一样,还是发布一个新问题来解决这个问题? 这确实基本上是一个无关的问题。但是您究竟是如何安装 PrimeFaces 的呢?您是说您手动将 PrimeFaces JAR 放入 /WEB-INF/lib 吗?因此实际上你没有使用 Maven 来构建? 问题是我没有成功安装Primefaces,正如here所报告的那样,所以我将primefaces-5.0.jar下载到WEB-INF/lib文件夹中。我可能搞砸了我的配置,这真的是第一次使用所有这些工具并使用 Java EE。

以上是关于在 @ViewScoped bean 之间传递对象而不使用 GET 参数的主要内容,如果未能解决你的问题,请参考以下文章

即使在刷新页面后,Firefox 也会在 JSF-Viewscoped-Managed-Bean 中保留数组的内容

在 JSF 中如何以及何时销毁 @ViewScoped bean?

如何检测和删除(在会话期间)不能被垃圾收集的未使用的 @ViewScoped bean

p:remoteCommand 销毁 @ViewScoped 托管 bean

JSF 2.x @ViewScoped 托管 bean 线程安全吗?

为啥在会话过期之前过期的@ViewScoped bean 不会被销毁