Using CDI Injection in a Servlet

Jonathan picture Jonathan · Mar 7, 2012 · Viewed 7.1k times · Source

I am attempting to @Inject a @SessionScoped bean into a Filter

@WebFilter("/*")
public class IdentityFilter implements Filter, Serializable {

    @Inject
    private LoginUser loginUser;
...

where LoginUser is @SessionScoped

The intention is for loginUser to represent the logged in user for the session.

The problem is it appears that I am not always getting the loginUser from the current session, I am getting 'leakage' between sessions as one session's LoginUser object is being shared with another session. Obviously this isn't good.

I am wondering if this is because the Filter object is a singleton, or at least reused between requests and sessions by the container (glassfish). (Right?)

Is there a better way to obtain the LoginUser object for the current session without using a property on the Filter?

Answer

Jonathan picture Jonathan · Mar 11, 2012

My problem is that there is only one instance of the Filter in the container, effectively a singleton. It seems that CDI injects the first session level object into the Filter at first use and then the Filter stores that reference forever, even for other sessions.

I've found this solution, to inject a factory object (Instance) which I can use to get the session instance each time the Filter runs, i.e.

 @WebFilter("/*")
 public class IdentityFilter implements Filter, Serializable {

      @Inject 
      private Instance<LoginUser> loginUserSource;

And in

 @Override
 public void doFilter(...)
      LoginUser login   = loginUserSource.get();

This seems to fix my problem.

Thanks