0

I've got a Stateful Session Bean which holds my login session, a JSF Session Bean and a Servlet Filter.

What I ned to do is to stop non logged users from accessing my pages, so I did a filter.

The doFilter() its like this :

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    String path = req.getRequestURI().substring(req.getContextPath().length());
    System.out.println(userManager.isLogged());
    if (userManager.isLogged() || path.equals("/") || path.equals("/index.xhtml") || path.startsWith(ResourceHandler.RESOURCE_IDENTIFIER) || path.startsWith("/resources/") || path.startsWith("/admin") || path.equals("/admin/login.xhtml")) {
        chain.doFilter(request, response);
    } else {
        request.getRequestDispatcher("/error.xhtml").forward(request, response);
    }
}

where userManager is found with :

private UserManagerLocal lookupUserManagerLocal() {
    try {
        Context c = new InitialContext();
        return (UserManagerLocal) c.lookup("java:global/UNILIFE/UNILIFE-ejb/UserManager!ejb.UserManagerLocal");
    } catch (NamingException ne) {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
        throw new RuntimeException(ne);
    }
}

Now, System.out.println(userManager.isLogged()); prints always false, while #{loginBean.logged} prints true.

Note that loginBean.logged is just

public boolean isLogged() {
    return userManager.isLogged();
}

and, in my Managed Bean, userManager is retrieved with

@EJB
private UserManagerLocal userManager;

Seems like that the servlet does not take the same SFSB as the JSF Managed Bean.

What am I doing wrong?

EDIT : new code

servlet

UserManagerLocal userManager = lookupUserManagerLocal();
private UserManagerLocal lookupUserManagerLocal() {
    try {
        Context c = new InitialContext();
        UserManagerLocal userM = (UserManagerLocal) c.lookup("java:global/UNILIFE/UNILIFE-ejb/UserManager!ejb.UserManagerLocal");
        HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
        req.setAttribute("userManager", userM);
        return userM;
    } catch (NamingException ne) {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
        throw new RuntimeException(ne);
    }
}

jsf bean

@PostConstruct
public void init(){
    HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
    userManager = (UserManagerLocal) req.getSession().getAttribute("userManager");
}
StepTNT
  • 3,867
  • 7
  • 41
  • 82

2 Answers2

1

Each time you lookup the stateful session bean, you're creating a unique instance, so isLogged is presumably returning the default field value. You need to somehow store the stateful session bean instance in the HttpSession and retrieve that from your filter. I lack JSF expertise, so I don't know if there's a convenient way to share the stateful session bean instance or if you'll need to manually link the JSF bean to the stateful bean.

Brett Kail
  • 33,593
  • 2
  • 85
  • 90
0

Each JNDI lookup will return a new handle to bean. Therefore you are getting the default value while calling method, discarding previous activities. You need to save that reference(HttpSession) for further operations on it, as explained in other post.

Below is sample code to access session in JSF bean.

HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();

From request, you can get session & then placing in it.

session.setAttribute("userManager", userManager);

Now in filter, you can retrieve bean from request. Also, modify code accordingly.

Nayan Wadekar
  • 11,444
  • 4
  • 50
  • 73
  • I've tried it, but the servlet is accessed before my bean is created, so `req.getSession().getAttribute("userManager");` returns null and my filter dosen't work at all – StepTNT May 25 '12 at 10:44
  • @StepTNT You can then reverse the case. Set it in servlet & fetch in bean. – Nayan Wadekar May 25 '12 at 11:34
  • ...and now the NPE is thrown by the JSF Managed bean :\ – StepTNT May 26 '12 at 10:33
  • @StepTNT It seems you aren't getting bean in servlet & setting null, have you verified it. – Nayan Wadekar May 26 '12 at 16:46
  • @StepTNT But you haven't mentioned any exceptions or output of added code. Also, initialize context with server specific properties & proper JNDI lookup string. – Nayan Wadekar May 27 '12 at 12:18
  • I wrote it in my previous comment, my JSF Bean throws a NPE when I try to access the SFSB – StepTNT May 27 '12 at 12:41
  • @StepTNT As I already mentioned, it might happen servlet is failing to lookup the bean & putting null in session, so code in JSF will have NPE, try debugging further. – Nayan Wadekar May 27 '12 at 17:37