Jsf共享所有用户的信息

Igo*_*gor 0 session jsf

我有一个使用jsf和prime面的系统.

我想要:

在主页上显示所有登录用户的名称和实时总数.

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

需要查看范围,因为某些页面具有敏感信息.

提前致谢.

Xtr*_*ica 6

使@ApplicationScopedbean存储您想要在用户之间共享的所有信息.然后,您可以获得与用户私有相关的信息@ViewScoped.请记住,您可以从同一视图中引用它们.

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

让我们提供@ApplicationScopedbean 的基本实现(假设您使用的是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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

然后让我们假设你有一个@SessionScopedbean,它也保留了当前登录的用户.当HttpSession开始时创建UserBeanGeneralInfobean,并在用户登录时创建当前UserBean.将找到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);
    }

}
Run Code Online (Sandbox Code Playgroud)

并执行UserBean,这需要实现HttpSessionBindingListener,以便在它被删除之前得到通知HttpSession.如果你看一下,这个通知将触发一个UserBean#valueUnbound方法调用,bean从@ApplicationScoped托管bean中自行删除.这允许GeneralInfobean知道用户实际在线的内容.

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

}
Run Code Online (Sandbox Code Playgroud)

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

@ManagedBean
@ViewScoped
public class Page1Info{

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

<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" />
Run Code Online (Sandbox Code Playgroud)