Search code examples
javajax-rshttprequestcdistateless

HttpServletRequest injection on RequestScoped bean CDI


I'm looking for a way in order to inject a @RequestScoped custom class into my @Stateless JAX-RS endpoint:

I want each time the application receives a request my custom class is injected in my JAX-RS endpoint.

Custom class:

@RequestScoped
public class CurrentTransaction {

    private String user;
    private String token;

    @PersistenceContext(name="mysql")
    protected EntityManager em;

    @Inject HttpServletRequest request;

    public CurrentTransaction() {
        this.user = request.getHeader("user");
        this.token = request.getHeader("token");
    }

    //getters and setters ...
}

So, I declare my CurrentTransaction class as @RequestScoped in order to be initialized each time a request is received. In order to do this, I need to access to HttpServletResquest in order to get header parameters.

JAX-RS endpoint:

@Stateless
@Path("/areas")
public class AreasEndpoint {

   @PersistenceContext(unitName = "mysql")
   protected EntityManager em;

   @Inject
   protected CurrentTransaction current_user_service;

    @POST
    @Path("postman")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Authentication
    public Response create(AreaRequest request) {

        if (this.current_user_service.getUser() == null) {
            System.out.println("Go!!!");
            return Response.status(Status.FORBIDDEN).build();
        } else {
            System.out.println("---- user: " + this.current_user_service.getUser());
            System.out.println("---- token: " + this.current_user_service.getToken());
        }
    }

    // ...
}

CDI arrive to perform the constructor of CurrentTransaction class. However, HttpServletRequest request field is not initialized (injected).

What am I doing wrong?


Solution

  • A late answer on this one--maybe useful to other readers: dependency injection in CDI is done in the following order:

    1. the constructor is invoked
    2. fields are injected
    3. @PostConstruct annotated method is invoked

    The last point is where you want to step in for further initialization that needs access on the injected fields:

    @Inject HttpServletRequest request;
    
    public CurrentTransaction() {
        // field injection has not yet taken place here
    }
    
    @PostConstruct
    public void init() {
        // the injected request is now available
        this.user = request.getHeader("user");
        this.token = request.getHeader("token");
    }