来自同一浏览器的多个会话

时间:2014-03-30 23:50:45

标签: jsf session

我需要一点方向来理解JSF(2.2.6)中的会话。我试图找到一些文档,但我仍然遗漏了一些东西。

我有一个@RequestScoped登录bean,它在会话映射中保存参数,供其他会话范围的后备bean参考。他们通过PostConstruct方法得到用户信息,一切都很好。

但是,当使用多个窗口或用户未注销并直接返回登录页面时,逻辑会失败。 JSF将此视为同一会话,并且不调用@PostConstructs。

我很确定我可以使会话无效,但这并不能解决来自不同浏览器窗口的多个用户的问题。

任何指导或参考网站都将受到赞赏。

提前致谢! 约翰

1 个答案:

答案 0 :(得分:1)

会话对于每个浏览器窗口都是相同的,唯一的例外是使用匿名模式时:即chrome表现得像是同时打开两个浏览器。

拥有多个sesssions的另一种方法是使用不同的服务器名称: http://localhost:8080/apphttp://127.0.0.1:8080/app可能不会共享一个会话。

然而会话永远不会重叠。

你的问题,如果我理解正确,是当一个登录的用户访问登录页面并重新登录,保留他的旧会话,这就是为什么会话bean不再是PostConstructed(独立于使用的窗口)

一般解决方案是禁止访问已登录用户的登录页面。 通常,当用户在没有事先注销的情况下重新登录时,容器将抛出AlreadyAuthenticatedException或类似的事件。

简而言之,只是一个等待代码的初步示例:

@ManagedBean
@SessionScoped
public class UserBean implements Serializable
{
    private static final long serialVersionUID = 1L;

    private User user;

    public boolean isLoggedIn()
    {
        return user != null;
    }

    public void login(String username, String password)
    {
        // maybe you want to check isLoggedIn() and either call logout() or throw an exception

        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        request.login(username, password);

        user = someDAO.loadFromDatabase(username); 
    }

    public void logout()
    {
        // maybe you want to check isLoggedIn() and either throw an exception or do nothing

        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        request.logout();

        user = null;

        // suggested for another scenario
        // request.getSession().invalidate();
    }

    // getters and setters
}

@ManagedBean
@SessionScoped
public class OperationBean implements Serializable
{
    private static final long serialVersionUID = 1L;

    @ManagedProperty("#{userBean}")
    private UserBean userBean;

    public void execute()
    {
        if(!userBean.isLoggedIn())
        {
            FacesContext.getCurrentInstance().getExternalContext().redirect("login.jsf");
            return;
        }

        User user = userBean.getUser();

        // do something 
    }

    // getters and setters
}

使用这种组合,而不是使用OperationBean的@PostContruct我使用了@ManagedProperty,因此OperationBean包含对用户的始终最新的引用,而不需要多次重新登录。