【问题标题】:JSF/Spring Session is shared between usersJSF/Spring Session 在用户之间共享
【发布时间】:2012-07-06 18:48:50
【问题描述】:

我有一个 JSF 管理的会话范围 bean。它也是一个弹簧组件,因此我可以注入一些字段:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.springframework.stereotype.Component;

@ManagedBean
@SessionScoped
@Component
public class EpgBean {...}

问题是会话是在用户之间共享的!如果一个用户做了一些事情并且另一台计算机上的另一个用户连接,他会看到另一个用户的 SessionScoped 数据。

是不是因为 spring @Component 会迫使 bean 成为单例?处理这个问题的正确方法是什么?

【问题讨论】:

  • 我不使用 Spring,但理论上您应该摆脱那些未使用的 JSF 托管 bean 注释(因为那只会让您感到困惑;如果您使用另一个框架来管理,它们根本不会被使用bean)并添加一个 Spring 特定的范围注释,例如 @Scope("session") 左右(它确实默认为“应用程序”范围,就像当没有声明 JSF 特定范围注释时 JSF 默认为“无”范围一样)。跨度>

标签: spring session jsf


【解决方案1】:

我使用的方法是将托管 bean 保留在 JSF 容器中,并通过托管属性上的 EL 将 Spring bean 注入其中。见related question

为此,在faces-config.xml 中设置SpringBeanFacesELResolver,这样JSF EL 就可以解析Spring bean:

<application>
    ...
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    ...
</application>

之后,您可以像这样在 @ManagedBean 注释的 bean 中注入 Spring bean:

@ManagedBean
@ViewScoped
public class SomeMB {
    // this will inject Spring bean with id someSpringService
    @ManagedProperty("#{someSpringService}")
    private SomeSpringService someSpringService;

    // getter and setter for managed-property
    public void setSomeSpringService(SomeSpringService s){
        this.someSpringService = s;
    }
    public SomeSpringService getSomeSpringService(){
        return this.someSpringService;
    }
}

可能有比这更好的方法,但这是我最近一直在使用的方法。

【讨论】:

  • 谢谢,我没有考虑过使用 ManagedProperty。但是我相信我的原始方法(声明为 spring 组件)更好,因为您不必通过 EL 显式编写注入 bean 的名称,因为您可以自动装配它们。
【解决方案2】:

我使用 spring 范围注释 @Scope("session") 而不是 JSF @SessionScopped 解决了这个问题。我想既然 spring 被配置为 FacesEl 解析器,那么重要的是 spring 作用域,而 JSF 作用域被忽略了。

【讨论】:

  • 如果您可以将此帖子标记为答案,将会很有帮助。
猜你喜欢
  • 2017-05-09
  • 2012-04-19
  • 2018-09-15
  • 2011-08-26
  • 2017-09-23
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多