JSF:在启动应用程序的两个实例时避免会话范围内的变量冲突

JSF:在启动应用程序的两个实例时避免会话范围内的变量冲突,jsf,Jsf,我有一个JSF应用程序,它大量使用会话范围的变量。新的要求是用户应该能够打开N个应用程序。然而,由于大部分状态是会话范围,当客户端打开应用程序的第二个实例时,第一个应用程序的视图数据会流入新打开的应用程序 此时,将所有会话范围的bean更改为请求范围的bean将非常困难。有没有一种方法可以在更高的层次上解决这个问题,可以将外部(客户端)会话映射到一个或多个内部(由JSF人工创建和使用)会话对象 您可以控制如何通过(提供包含ExternalContext的FacesContext)将会话提供给JS

我有一个JSF应用程序,它大量使用会话范围的变量。新的要求是用户应该能够打开N个应用程序。然而,由于大部分状态是会话范围,当客户端打开应用程序的第二个实例时,第一个应用程序的视图数据会流入新打开的应用程序


此时,将所有会话范围的bean更改为请求范围的bean将非常困难。有没有一种方法可以在更高的层次上解决这个问题,可以将外部(客户端)会话映射到一个或多个内部(由JSF人工创建和使用)会话对象

您可以控制如何通过(提供包含ExternalContext的FacesContext)将会话提供给JSF应用程序。这需要在faces-config.xml中进行配置,以便JSF可以在初始化期间获取它。如果使用MyFacesConfigFactory(FacesConfigFactory)形式的构造函数,JSF将传递先前配置的工厂,允许您修饰底层实现

您可能会遇到一些问题:

  • 为了创建子会话,您需要控制“打开应用程序”的含义。例如,创建子会话的窗体
  • 您需要一些机制来将请求与会话相匹配——可能是通过URL编码方法(这需要严格使用;行为良好的组件已经在使用这些方法)
  • 你需要一整层的会话管理代码——我想人们只要打开应用程序的多个“实例”就可以创建巨大的HTTP会话
  • 可能有很多边缘条件和其他我没有想到的事情

这是解决这个问题的一种有趣的方法,但我不希望它是一个快速解决方案。

有一些框架可以为您解决这个问题,但我不确定采用新框架是否是一个可接受的解决方案


Seam提供了基于会话的范围的概念,它可能会做您需要它做的事情。我还知道Spring有一个等价的作用域

您真的需要直接使用会话对象吗?为什么不使用会话范围映射,将唯一的“子会话”ID映射到子会话属性的映射?缺点是,您需要在每个页面上包含子会话ID,作为每个客户端请求中包含的隐藏参数,并且所有EL for会话属性都需要类似于“#{subSession.mySubSessionId.myAttribute}”。您可能会遇到其他问题,因为重定向或浏览器刷新可能会破坏您的子会话ID


总的来说,我会寻找一个框架解决方案。框架解决方案有更好的机会减少bug,这也意味着您可以创建和维护更少的代码。在为您处理了这些细节之后,您可以更轻松地专注于实际的应用程序开发。

如果我没记错的话,Apache Orchestration是向JSF添加对话范围的另一个选项。Tomahawk(带有saveState组件)或RichFaces(keepAlive组件)也可以提供此类功能。。。