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