3

好的,我知道范围问题一直都会出现,但我对解决方案的稍微不同的方法很感兴趣。是介于和之间的@ViewScope奇妙桥梁。@RequestScope@SessionScope

但是,仍然有一个常见的用例(至少对我而言),我真的不想使用@SessionScope,但我需要几个视图中的数据。一个非常简单的情况是,当我根据先前的选择将多个数据表链接在一起时。

完全可以在<f:paramView>地址中使用和传递单个甚至几条数据作为参数,然后再次从数据库中检索所有内容。我更感兴趣的是找到一种方法来创建 bean 状态/变量的“快照”,创建新的@ViewScope,然后将“快照状态”“恢复”到新的 bean。

这样的事情存在吗?想法?意见?

4

2 回答 2

2

我不知道这是否是“公认的解决方案”,但我已经实现了一个适合我的想法。(反馈赞赏!)

所以我创建了一个@SessionScoped带有几个静态映射的类:

private static Map<String, Object> objectVariableMap;

// Getters, setters and methods etc. are omitted for simplicity

我的想法是我指定了一个接受String作为键和Object作为值的映射。我没有专门设置对象的类型以允许我在其中存储任何类型的对象。需要注意的是,在检索对象时需要确定对象的类型,以便可以将其转换回其原始类型。

现在是从第一个设置数据的时候了@ViewScoped。我生成一个随机 UUID(或您想要的任何内容)作为 Map,然后将设置为我正在使用的对象(即 . this,或者实际上您可能想要传递到下一个视图的任何其他对象)。将键、值保存到地图中并将 URL 参数设置为键。

我从不热衷于在 URL 参数中传递用户 ID 等数据(即使它已加密)。这个想法还有一个额外的好处,那就是提供具有可指定生命周期的一次性 URL 值。

在接收端(即新@ViewScopedbean 或任何其他范围),您使用读取 URL 参数(映射键)<f:paramView>,然后使用preRenderView事件来检索和设置使用的对象。

此时,您可以选择从 Map 中删除密钥对并使检索该对象的能力无效,或者您可以通过在有任何更改时简单地更新对象来保持密钥对更长的时间。

更新:从概念上讲,这真的很成功(至少对我来说)。我围绕这个概念创建了一些有用的方法和类,以使其更加通用。如果有人想要更具体的说明,或者如果有人想要,我什至可以创建一个小型图书馆。

于 2013-03-22T10:21:02.913 回答
1

您可以为此使用 CDI“对话范围”。这比会话范围窄,但比视图范围宽。

如果您传递参数的页面是一个单元,您还可以在 JSF 2.2 中将它们设为流并使用流范围。

像 CODI 这样的项目提供了可以在页面之间使用的各种其他范围。

于 2013-03-23T14:14:47.293 回答