Jsf共享所有用户的信息

时间:2013-11-28 12:14:18

标签: jsf session

我有一个使用jsf和prime faces的系统。

我想:

在主页上显示所有已记录的用户名称及其实时总数。

在每个页面上显示相同但与每个特定页面相关的内容。我希望用户知道谁在同一时间查看同一页面。

需要查看范围,因为某些页面包含敏感信息。

提前致谢。

1 个答案:

答案 0 :(得分:6)

创建一个@ApplicationScoped bean存储您要在用户之间共享的所有信息。然后,您可以在@ViewScoped中获取与用户的私有信息相关的信息。请记住,您可以从同一视图中引用它们。

话虽如此,主要的挑战是知道用户何时以某种方式完成会话。从JSF的角度来看,我理解这是不可能知道的,所以诀窍是更进一步,并在解释HttpSessionBindingListener时使用here

让我们提供@ApplicationScoped bean的基本实现(假设您正在使用JSF 2和EL 2.2,它允许您将params传递给服务器方法):

@ManagedBean
@ApplicationScoped
public class GeneralInfo{

    List<UserBean> onlineUsers;

    //Getters and setters

    public int numberUsersWathingThis(String viewId){
        int result = 0;
        for (UserBean ub : onlineUsers){
            if (ub.getCurrentViewId().equals("viewId")){
                result++;
            }
        }
        return result;
    }

}

您可以在此处存储实际在线的用户列表。假设每个用户都有一个String属性指定显示的当前视图,我们需要一个简单的迭代来检索当前有多少用户在指定的视图ID中。

然后让我们假设你有一个@SessionScoped bean,它也保留了当前登录的用户。当HttpSession开始时创建该bean,并在用户登录时创建当前UserBean。UserBean将找到GeneralInfo bean并将其注入其中。

@ManagedBean
@SessionScoped
public class SessionBean{

    UserBean userBean;

    //Create your UserBean when user logs into the application

    public void setCurrentPage(String currentViewId){
        userBean.setCurrentViewId(currentViewId);
    }

}

UserBean的实施,需要实施HttpSessionBindingListener才能在从HttpSession移除之前得到通知。如果你看一下,这个通知将触发一个UserBean#valueUnbound方法调用,bean从@ApplicationScoped托管bean中自行删除。这允许GeneralInfo bean知道用户实际在线

public class UserBean implements HttpSessionBindingListener{

    @ManagedProperty(value="#{generalInfo}")
    GeneralInfo generalInfo;

    @PostConstruct
    public void postConstruct(){
        generalInfo.addUser(this);
    }

    @Override
    void valueUnbound(HttpSessionBindingEvent event){
        generalInfo.removeUser(this);
    }

    //Getter and Setters

}

在那之后,作为最后一个挑战,我们想知道当前用户正在观看什么。解决这个问题的一种简单方法是使用管理当前视图的@ViewScoped bean来更新存储在UserBean bean中的@SessionScoped。因此,让我们访问当前的@ViewScoped bean并更新用户看到的内容:

@ManagedBean
@ViewScoped
public class Page1Info{

    @ManagedProperty(value="#{sessionBean}")
    SessionBean sessionBean;

    public void initialize(ComponentSystemEvent event){
        sessionBean.setCurrentPage("page1.xhtml");
    }

}

page1Info#initialize方法被称为preRenderView事件(对JSF 2.2+使用f:viewAction)。所以最后会有某种观点:

<f:metadata>
    <f:event type="preRenderView"
        listener="#{page1Info.initialize}" />
</f:metadata>
<h:outputText value="There are #{fn:length(generalInfo.onlineUsers)} users online" />
<h:outputText value="There are #{numberUsersWathingThis("page1.xhtml")} users watching this" />