I believe the JAX-RS spec (which defines @Context) only defines the use of @Context with JAX-RS objects. It does not define how it should be injected into CDI objects.
You have some options though. There are open frameworks like Seam 3 and DeltaSpike (and probably CODI offers this as well) which can allow you to @Inject your HTTP Request in to your CDI beans. You could also do it yourself with a servlet listener and a producer method for the request/response. On Sun, Apr 7, 2013 at 5:32 PM, Antoine Reilles <[email protected]> wrote: > Hi, > > I'm running into issues when defining a RequestScoped CDI bean to be > injected in a jax-rs service, and initialized with information from the > http request. > My first problem is that the @Context HttpServletRequest that gets injected > in the CDI bean is invalid (the threadlocal proxy points to null, thus > raising NPE when a method is called on the object) whenever the same > @Context HttpServletRequest is not injected in the jax-rs context. If the > servletrequest in injected in the jax-rs endpoint, then it is properly > available from the CDI bean. > The second issue I have is that injecting the HttpServletResponse in the > CDI bean makes it available with the same limitations as the > HttpServletRequest, but it is no more available (again, a thread local > proxy pointing to null) in the @PreDestroy method of the CDI bean. > > Here are samples of what I used to test, I can provide a complete sample if > it is useful. > > The service is simply: > @Path("service") > @Produces(MediaType.TEXT_PLAIN) > public class Service { > @Context HttpServletRequest request; > @Context HttpServletResponse response; > @Inject Ctx ctx; > > @GET > public String foo() { > return "foo: "+ctx; > } > } > > with the two @Context annotated fields triggering different behavior in the > CDI bean when commented out. > The CDI bean itself is: > @RequestScoped > public class Ctx { > > @Context HttpServletRequest request; > @Context HttpServletResponse response; > private String requesturi; > Ctx() { > requesturi = null; > } > > @PostConstruct > public void postConstruct() { > ServletRequest localreq = > ((org.apache.openejb.rest.ThreadLocalHttpServletRequest)request).get(); > if (null == localreq) { > System.out.println("null request injected"); > } else { > requesturi = request.getRequestURI(); > } > System.out.println("Ctx @PostConstruct:"+this); > ServletResponse localResp = > ((org.apache.openejb.rest.ThreadLocalHttpServletResponse)response).get(); > if (null == localResp) { > System.out.println("null response injected"); > } else { > System.out.println("Ctx @PostConstruct Response: > "+response.getStatus()); > } > } > > @PreDestroy > public void preDestroy() { > System.out.println("Ctx @PreDestroy:"+this); > ServletResponse localResp = > ((org.apache.openejb.rest.ThreadLocalHttpServletResponse)response).get(); > if (null == localResp) { > System.out.println("null response injected at preDestroy"); > } else { > System.out.println("Ctx @PreDestroy Response: > "+response.getStatus()); > } > } > } > > I had to resort to casts to ThreadLocalHttpServletRequest to test the > injected proxies, since calling any method on a proxy pointing null > triggers an NPE, to display traces. > When the two @Context annotated fields are present in the Service class, I > do get traces like this: > Ctx @PostConstruct:Ctx: service > Ctx @PostConstruct Response: 200 > Ctx @PreDestroy:Ctx: service > null response injected at preDestroy > > and when the two fields are commented out in the Service class, the traces > are: > null request injected > Ctx @PostConstruct:Ctx: null > null response injected > Ctx @PreDestroy:Ctx: null > null response injected at preDestroy > > > I tested this behavior with 1.5.1, 1.5.2 and todays 1.6.0 snapshot, and got > the very same behavior. > > Any suggestions on how I could make this work ? > > Best regards, > antoine >
