I have a bunch of JAX-RS resources that provide an API for a new WebService. In order to understand what's happening, I'd like to store information about each request in a data warehouse. In my mind, this is a perfect example for a cross-cutting concern, which could be implemented by a ResourceFilter
, right?
So I built a DataWarehouseService
which is supposed to store stuff in the DB:
@Stateless
@LocalBean
public class DataWarehouseService {
public void logApiCall(ContainerRequest cr) {
// get interesting fields from request, store in DB
...
}
}
And here's my filter:
public class LoggingResourceFilter implements ResourceFilter {
Logger log = Logger.getLogger(this.getClass().getName());
@EJB
DataWarehouseService dwh;
@Override
public ContainerRequestFilter getRequestFilter() {
return new ContainerRequestFilter() {
@Override
public ContainerRequest filter(ContainerRequest cr) {
log.info("Incoming request: "+
cr.getHeaderValue("user-agent") +" "+
cr.getMethod() +" "+
cr.getPath()
);
dwh.logApiRequest(cr);
return cr;
}
};
}
@Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
}
I inject the filter into my JAX-RS resources via annotation @ResourceFilters(LoggingResourceFilter.class)
on class-level.
The Filter-injection works fine, when I access one of the JAX-RS resources, the log statement ("Incoming request: ...") gets executed. But immediately afterwards, the call to the injected DataWarehouseService
's dwh.logApiRequest(cr)
fails with a Nullpointer - obviously the injection failed?!
What's the problem here? I thought, ResourceFilters
are managed and can use CDI. Am I wrong?
All of this runs on Glassfish 3.1.1, Jersey 1.8 is the JAX-RS provider. Would it make a difference if I used @Inject
?
Ok, I'm an idiot.
Adding a
@Stateless
annotation to theLoggingResourceFilter
fixed it.