获取SessionBean实例

时间:2013-04-30 21:11:31

标签: java eclipse jsf xhtml jboss5.x

我试图通过我的页面来保持SessionBean的范围,为此,我从这里开始学习一些教程,实际上,我正在尝试通过ExternalContext获取会话,如下面的代码:

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 {}

}

在这一行if(activeUserModel.getUsername()== null),我得到一个java.lang.NullPointerException,因为我没有实例化bean,但即使我实例化它,也没有用。

有什么问题?

2 个答案:

答案 0 :(得分:5)

您正在获取NPE,因为You cannot obtain a FacesContext object位于JSF工件的上下文之外(@ManagedBean@FacesConverter@FacesComponentPhaseListener等),相对于JSF请求。因此,sMap将在该行

之后评估为null

不确定您为什么选择首先通过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 :(得分:1)

如果会话范围bean为null,则表示尚未为会话创建它。这可能发生在新会话的第一次请求期间。您需要自己创建它并将其放在会话范围内。 JSF将在会话的剩余部分中重用它。

你抓住会话范围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实例,因此所有实例变量都将在所有请求/会话之间共享。换句话说:它不是线程安全的。