JSF/Spring会话在用户之间共享。

3

我有一个JSF管理的会话范围bean。它也是一个Spring组件,这样我就可以注入一些字段:

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

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

问题在于会话(session)被多个用户共享!如果一个用户执行了一些操作,而另一个来自另一台计算机的用户连接时,他会看到其他用户的SessionScoped数据。

这是因为Spring @Component会强制该bean成为单例吗?针对此问题的正确方法是什么?


2
我不使用Spring,但理论上你应该去掉那些未使用的JSF管理的bean注释(因为这只会让你困惑;如果你使用另一个框架来管理bean,它们根本不会被使用)并添加一个Spring特定的范围注释,类似于@Scope("session")(它默认为“application”范围,就像当没有声明JSF特定的范围注释时,JSF默认为“none”范围)。 - BalusC
2个回答

6

我使用Spring作用域注解@Scope("session")来解决问题,而不是使用JSF @SessionScoped。我猜想由于Spring被配置为FacesEl解析器,因此Spring作用域才是相关的,而JSF作用域则被忽略了。


如果您能将此帖子标记为答案,那将非常有帮助。 - Luiggi Mendoza

2
我使用的方法是将托管的Bean保留在JSF容器中,并通过托管属性上的EL将Spring Bean注入它们。请参见相关问题
为此,请在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的名称,而可以使用自动装配。 - kgautron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接