2013-11-28 67 views
0

我有一個系統使用jsf和主要面孔。Jsf共享所有用戶的信息

我想:

在主頁上顯示所有的登錄用戶名和實時他們的總數。

在每個頁面上顯示相同但與每個特定頁面相關的內容。我希望用戶知道誰在同一時間查看同一頁面。

由於某些頁面包含敏感信息,因此需要查看範圍。

在此先感謝。

回答

5

讓一個@ApplicationScoped bean存儲您想要在用戶之間共享的所有信息。然後,您可以在@ViewScoped中獲得有關用戶私人信息的信息。請記住,您可以從同一視圖中引用它們。

話雖如此,主要的挑戰是知道用戶何時以某種方式完成會話。從JSF的角度來看,我知道這是不可能知道的,所以訣竅是更進一步,並使用HttpSessionBindingListener,因爲它解釋爲here

我們提供@ApplicationScoped豆的基本實現(假設你正在使用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,它也保持當前登錄的用戶。該Bean在HttpSession開始時創建,並在用戶登錄時創建當前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刪除通知。如果你看一下,這個通知將觸發一個​​方法調用,該方法調用將自己從@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來更新存儲在@SessionScoped bean中的UserBean。因此,讓我們把訪問當前@ViewScoped豆到和更新用戶正在看:

@ManagedBean 
@ViewScoped 
public class Page1Info{ 

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

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

} 

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" /> 
+0

用戶如何在同一個甚至不同的會話中的多個瀏覽器標籤中打開多個頁面? ;)調查努力的榮譽,並提供一個開球的例子無論如何。 – BalusC

+0

這將是可以使用隱藏的輸入字段管理的東西,例如?現在不能用其他方式來思考。無論如何,感謝您的問候並隨時編輯它,這個答案是從您的帖子中學到的! –

+1

@Xtreme這是一個非常詳細和周到的答案。我的問候也是如此。 – skuntsel