Stateful Bean : serlvet takes wrong value while managedBean not

378 views Asked by At

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

There are 2 answers

0
Brett Kail On

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.

7
Nayan Wadekar On

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.