Reputation: 1436
Say I have a web service / a REST resource that is called with some HTTP header parameters. The resource method builds a complex data object (currently a POJO) and eventually returns it to the client (via Gson as JSON, but that doesn't matter).
So I have this call hierarchy:
@Path(foo) ProjectResource @GET getProject()
-> new Project()
-> new List<Participant> which contains lots of new Participant()s
-> new Affiliation()
If I want the Affiliation
object to be e.g. populated in English or German depending on a header parameter, I have to pass that as a parameter down the chain. I want to avoid having to do that. Maybe this is just fundamentally impossible, but it feels so wrong. All these objects only live inside the request, so wouldn't it be convenient to be able to access information tied to the request from anywhere?
I was hoping I could e.g. define a CDI @RequestScoped
object that initialized itself (or gets populated by some WebFilter) and that I can then inject where I might need it.
But obviously that doesn't work from inside the POJOs, and I also had trouble getting hold of the headers from inside the request-scoped object.
I've read many SO questions/answers about EJBs and JAX-RS Context and CDI but I can't wrap my head around it.
Am I expecting too much? Is passing down the parameter really the preferred option?
Upvotes: 1
Views: 2950
Reputation: 131067
If I understand what you need, you can try the following (just wrote this solution from the top of my head, but it should work):
Define a class annotated with @RequestScoped
which will store the data you need:
@RequestScoped
public class RequestMetadata {
private Locale language;
// Default constructor, getters and setters ommited
}
Ensure you are using the @RequestScoped
annotation from the javax.enterprise.context
package.
Create a ContainerRequestFilter
to populate the RequestMetadata
:
@Provider
@PreMatching
public class RequestMetadataFilter implements ContainerRequestFilter {
@Inject
private RequestMetadata requestMetadata;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
requestMetadata.setLanguage(requestContext.getLanguage());
}
}
And then you can finally perform the injection of the RequestMetadata
using @Inject
:
@Stateless
public class Foo {
@Inject
private RequestMetadata requestMetadata;
...
}
Please, be aware that anywhere is too broad: The injection will work into beans managed by the container, such as servlets, JAX-RS classes, EJB and CDI beans, for example.
You won't be able to perform injections into beans created by yourself neither into JPA entities.
Upvotes: 6