2013-04-30 75 views
1

我嘗試保持SessionBean的範圍的通過量我的網頁,爲此,我也跟着從這裏一些教程,實際上,我試圖讓通過量的ExternalContext會話,如下面的代碼:獲取會話Bean實例

public class LoginFilter implements Filter{ 

ProfileBean pBean = new ProfileBean(); 
ActiveUserModel activeUserModel; 
ExternalContext tmpEC; 
Map sMap;  

public void destroy() {} 

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 

    tmpEC = FacesContext.getCurrentInstance().getExternalContext(); 
    sMap = tmpEC.getSessionMap(); 
    activeUserModel = (ActiveUserModel) sMap.get("ActiveUserModel");   

    String username = SecurityAssociation.getPrincipal().getName();    

    if(activeUserModel.getUsername() == null) 
    { 
     try { 
      pBean.consultaProfile(username);    

     } catch (SQLException e) { 
      e.printStackTrace(); 
     } catch (NamingException e) { 
      e.printStackTrace(); 
     } 
    }else{ 
     }   

    filterChain.doFilter(servletRequest, servletResponse);  
} 

public void init(FilterConfig filterConfig) throws ServletException {} 

}

在這一行,如果(activeUserModel.getUsername()== NULL),我得到一個顯示java.lang.NullPointerException因爲我不實例化豆,但即使我實例化,沒」工作。

有什麼問題嗎?

+0

[您不能直接獲得一個過濾器'FacesContext'參考(HTTP:/ /stackoverflow.com/a/14394992/1530938)像你試圖在這裏做的。 – kolossus 2013-04-30 23:45:05

回答

5

你得到NPE因爲You cannot obtain a FacesContext object之外的JSF神器(@ManagedBean@FacesConverter@FacesComponentPhaseListener等),面對面的人JSF請求的上下文。因此,sMap將在該行之後評估爲空

不確定您爲什麼選擇首先通過FacesContext查找會話。你可以很容易地做到這一點:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 

    //Get a hold of the http request 
    HttpServletRequest req = (HttpServletRequest)request; 

    //Access the HttpSession associated with the request 
    HttpSession session = req.getSession(false); 

    //Take what you want from the session 
    activeUserModel = (ActiveUserModel) session.getAttribute("ActiveUserModel");   

    String username = SecurityAssociation.getPrincipal().getName();    

     if(activeUserModel.getUsername() == null) { 
      try { 
      pBean.consultaProfile(username);    

      } catch (SQLException e) { 
      e.printStackTrace(); 
      } catch (NamingException e) { 
      e.printStackTrace(); 
      } 
      }else{ 
     }   

     filterChain.doFilter(servletRequest, servletResponse);  
    } 

在JSF的SessionScope,就像你已經知道是對HttpSession一個門面。所以,你可以很容易地將手伸入基本HttpSession和拉都@SessionScoped變量,對環島FacesContext替代你探索

+1

非常好的解釋! – skuntsel 2013-05-01 07:17:17

+0

我明白了,但在其他類中,我不使用'ServletRequest'和'ServletResponse'? – 2013-05-01 13:09:23

+0

@MarcosFontana「其他類」是JavaEE中的一個模糊語句。不同的上下文(Servlet?Managed Bean?)將需要不同的訪問方法來實現相同的結果 – kolossus 2013-05-01 13:43:01

1

如果會話scoped bean是null,那麼它只是表示它尚未爲會話創建。這可能會在新會議的第一次請求期間發生。你必須自己創建它並將它放在會話範圍中。 JSF將在會話的剩餘部分重用它。

你抓取session scoped bean的方式有點笨拙。你從JSF的底層獲得了原始的Servlet API。您也可以使用ExternalContext#getSessionMap()來管理會話屬性。

Map<String, Object> sessionMap = externalContext.getSessionMap(); 
LoginBean loginBean = (LoginBean) sessionMap.get("loginBean"); 
if (loginBean == null) { 
    loginBean = new LoginBean(); 
    sessionMap.put("loginBean", loginBean); 
} 
// ... 

請注意,您不應該將bean聲明爲PhaseListener的實例變量。在應用程序的整個生命週期中都有一個PhaseListener實例,所有實例變量都將在所有請求/會話中共享。換句話說:它不是線程安全的。

+2

您錯過了一個重要的觀點:OP無法訪問過濾器中的'FacesContext'。在這個事實之後,你在這裏假設的其他事實將不再相關。我也找不到任何OP指向'PhaseListener'的地方。也許你的意思是'FacesContext'。在你的回答中有一些誤解在這裏 – kolossus 2013-05-01 00:07:53