1

im trying to keep a SessionBean scoped throug my pages, and for this, i followed some tutorials from here, and actually, I'm trying to get the session throug ExternalContext, like the following code:

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

}

In this line if(activeUserModel.getUsername() == null), i get a java.lang.NullPointerException because I'm not instantiating the bean, but even if I instantiate it, didn't work.

There is something wrong?

  • [You can't directly obtain a reference to `FacesContext` in a filter](http://stackoverflow.com/a/14394992/1530938) like you've tried to do here. – kolossus Apr 30 '13 at 23:45

2 Answers2

5

You're getting the NPE because You cannot obtain a FacesContext object outside of the context of a JSF artifact(@ManagedBean, @FacesConverter,@FacesComponent,PhaseListener etc), vis-a-vis a JSF request. As a result, sMap will evaluate to null after that line

Not sure why you opted to go looking for the session through the FacesContext in the first place. You can just as easily do this:

   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);      
     }

The SessionScope in JSF, like you already know is a facade on the HttpSession. So you can just as easily reach into the basic HttpSession and pull all @SessionScoped variables, as against the roundabout FacesContext alternative you were exploring

Community
  • 1
  • 1
kolossus
  • 20,559
  • 3
  • 52
  • 104
  • I got it, but and in other classes that i do not use 'ServletRequest' and 'ServletResponse'? – Marcos Fontana May 01 '13 at 13:09
  • @MarcosFontana "Other classes" is an ambiguous statement in JavaEE. Different contexts(Servlet? Managed Bean?) will require different access methods to achieve the same result – kolossus May 01 '13 at 13:43
  • Ok @kolossus, but if i need to recover the object in session, in a class that does not belong to any JSF artifact, like a DAO class, how should i proceed? Because i've seen some solutions using HttpSession, but i do not have the HttpRequest/Response to use it. – Marcos Fontana May 01 '13 at 21:38
  • @MarcosFontana, whatever class it is, it must be within a web application. If it's within a web application, there will be an `HttpServletRequest/Response` under the hood. It becomes a matter of navigating there. Like I said before "a class" is an extremely ambiguous statement. The fact of the matter is, as long as you're in the context of a web application, you'll always be able to find your way to the session. DAO classes will be used within a JEE construct: EJB, Webservice, something, anything. As long as it's not on a desktop J2SE, there'll always be a HttpRequest underlying it – kolossus May 01 '13 at 21:51
1

If the session scoped bean is null then it simply means that it hasn't been created for the session yet. This can happen during the very first request of a fresh session. You've to create it yourself and put it in the session scope yourself. JSF will just reuse it in the remnant of the session.

Your way of grabbing the session scoped bean is a bit clumsy. You're getting the raw Servlet API from under the JSF's hoods. You could also just use ExternalContext#getSessionMap() to manage the session attributes.

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

Note that you shouldn't declare the bean as an instance variable of the PhaseListener. There is namely a single PhaseListener instance throughout the application's lifetime, so all instance variables would be shared among all requests/sessions. In other words: it's not threadsafe.

chiru
  • 812
  • 5
  • 17
  • 32
  • 2
    You're missing a vital point here: OP does not have access to `FacesContext` in a filter. The other facts you've posited here would no longer be relevant after that fact. I also can't find anywhere OP's referring to a `PhaseListener`. Perhaps you mean the `FacesContext`. A number of misconceptions in your answer here – kolossus May 01 '13 at 00:07