2014-06-11 107 views
1

嗯,我有一些會話屬性必須對所有應用程序(DAO,Business Object,Beans等)都可訪問。管理會話屬性以在所有Web應用程序中訪問

我無法創建具有靜態屬性的類,因爲靜態屬性會共享到不同的會話。

IE:應用程序中的用戶登錄,我需要保存登錄的小時,我需要將此值存儲在會話屬性中,因爲在我的應用程序的某個點(如BO(業務對象))中,我需要知道用戶登錄應用程序時。

我不能在我的應用程序的某些地方使用HttpRequest,我需要一些其他解決方案。

+1

你的問題讀起來就像有一個更根本的問題,設計與應用。業務對象應該爲應用程序中的其他組件提供服務,而不是相反。業務對象應該位於提供必要信息的位置,因此組件可以根據需要調用業務方法(比如只是在某處存儲某些信息,然後讓商業對象提取數據)。所有,告訴,你可以嘗試一個'@ ApplicationScoped'豆,它有一個你感興趣的數據地圖 – kolossus

+0

我提高了@kolossus,但他希望的會話範圍不是@/ApplicationScoped – VeenarM

回答

0
  1. 編寫一個POJO,其中包含您需要的所有「請求範圍」屬性,例如「登錄小時數」;
  2. javax.servlet.Filter

    public PojoFilter implements javax.servlet.Filter { 
    
        private static final ThreadLocal<Pojo> POJO = new ThreadLocal<Pojo>(); 
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) { 
         try { 
          Pojo pojo = createPojoFrom(request); 
          POJO.set(pojo); 
          filterChain.doFilter(request, response); 
         } finally { 
          POJO.remove(); 
         } 
        } 
    
        public static currentPojo() { 
         return POJO.get(); 
        } 
    
        ... 
    } 
    
  3. 呼叫PojoFilter.currentPojo()在任何你需要這些值。

很明顯,這可以設計得更好,使過濾器不會泄漏到代碼的其餘部分,但是這應該給你的想法。

+0

所以,我想我可以創建一個ThreadLocal的地圖,我可以返回具有特定名稱和特定值的ThreadLocal。每個會話對這個MAP都是一個不同的值,它是正確的嗎? –

+0

我不這麼認爲。 ThreadLocal的精妙之處在於,每個控制線程都會獲得您創建的Pojo的單獨實例。因此,如果您的應用程序在N個線程上處理N個請求,那麼在每個請求的持續時間內將存在N個不同的Pojos。如果你願意,你的Pojo可能是一個地圖,但這是一個非常鬆散的抽象 –

+0

我無法理解你的理想,你能給我更多的細節嗎? –

0

你已經在JSF中標記了這個,所以我打算給你一個jsf響應和/或通用的。

a)創建一個@SessionScoped - ManagedBean並將其值應用於其中,然後@ManagedProperty將其注入到您要訪問的要求位置(如果需要,創建一個門面)。 b)只需創建一個「數據模型」對象,將您的信息存儲在其中,並將其設置到會話中。 E.g

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("userContext", context); 
+0

第二個解決方案非常好,但優雅,但問題是,當我嘗試訪問FacesContext.getCurrentInstance()這將返回NULL。 –

+0

那你確定你確實在使用JSF嗎? – VeenarM

+0

是的,我正在使用JSF。 –

0
Since user id is unique, we can utilize this fact to implement your problem in simpler way as follows(My solution consider that all incoming request goes through common servlet/filter, I am using filter here): 

a) Create a utility class as: 

public class AppUtlity { 
    private static Map<String, Date> userLoginTimeStampMap = new HashMap<String, Date>(); 

    public static void addLoginTimeStamp(String userId) { 
     synchronized(AppUtlity.class) { 
      Date date = new Date(); 
      userLoginTimeStampMap.put(userId, date); 
     } 
    } 

    public static Date getUserLoginTimeStamp(String userId) { 
     synchronized(AppUtlity.class) { 
      return userLoginTimeStampMap.get(userId); 
     } 
    } 
} 

b) In doFilter method of your filter write code as below: 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) { 
     try { 
      String userId = user.getUserId(); 
      AppUtlity.addLoginTimeStamp(userId); 
     } finally { 
      // do whatever u want to do 
     } 
    } 

c) Now in any class like service or dao, you can easily get user login timestamp as below: 

Date date = AppUtlity.getUserLoginTimeStamp(userId); 

I hope this solution is feasible. 
相關問題