Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using CDI Injection in a Servlet

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?

like image 448
Jonathan Avatar asked Mar 07 '12 21:03

Jonathan


People also ask

How does CDI work java?

Overview. CDI (Contexts and Dependency Injection) is a standard dependency injection framework included in Java EE 6 and higher. It allows us to manage the lifecycle of stateful components via domain-specific lifecycle contexts and inject components (services) into client objects in a type-safe way.

What is Weld servlet?

Weld is the reference implementation of CDI for the Java EE Platform. Weld is integrated into many Java EE application servers such as WildFly, JBoss, GlassFish, and others. Weld can also be used in plain servlet containers (Tomcat, Jetty) or Java SE.

How do you make a class injectable in Java?

In order to inject class it should be: Concrete class (i.e not abstract or interface) or it should annotated as @Decorator. Should have no-arg constructor or constructor annotated with @Inject.


1 Answers

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

like image 78
Jonathan Avatar answered Sep 20 '22 14:09

Jonathan