Reputation: 70
I have a web application with JAX-RS, CDI and EJB. In each resource I inject a Stateless SessionBean, and my question is whether it is possible to inject the same instances into a provider of JAX-RS and the Stateless SesionBean. I am trying to pass some data that come in each request to the Stateless SesionBean from a ContainerRequestFilter. All EJB components are accessed only by jax rs resources.
Example:
public class Bean {
private String attr;
// getter and setter
}
@Stateless
public class BeanService {
@Inject
Bean bean;
public void doStuff() {
bean.getAttr();
// do something with bean.attr
}
}
@Path("/bean")
public class BeanResource {
@Inject
BeanService service;
@GET
public void doStuff() {
service.doStuff():
}
}
@Provider
public class BeanRequestFilter implements ContainerRequestFilter {
@Inject
Bean bean;
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
String data = null; // <- get data from request
bean.setAttr(data);
}
}
Update
Change the Bean for Pojo, my only intention is use a class that hold some state that come in every request and can be transmited in each invocation, since the PojoResource to PojoService. I want to do it in this way because all the services retrive this data and I don't want to pass this as parameter on every method.
Upvotes: 0
Views: 472
Reputation: 3533
Before answering the question, Bean should never be updated. A concept of bean is that which provides a service, and uses data to process a request.
That said, you can of course provide data as bean, but then the data needs to be produced at one point to be used, and not to be updated.
I would therefore use the BeanRequestFilter
to produce the bean, and let the BeanService
inject the produced bean.
This notwithstanding however, i see that this is a request based data? is it a header data?, request parameter? Then i would suggest that you use the jax-rs @QueryParam
or @HeaderParam
or @PathParam
or @FormParam
or @CookieParam
within the jax-rs resource class, and then provide the data as a domain object parameter to your BeanService
thus:
@Path("/api/resource-path")
public class MyResource {
public void processSomething(@QueryParam("qparam") String param, @HeaderParam("hparam") String hParam) {
MyDomain domain = new MyDomain(qParam, hParam);
myService.process(domain);
}
}
Upvotes: 0
Reputation: 19445
This looks like your Bean
class is essentially request scoped, so changing it to:
@RequestScoped
public class Bean {
...
}
should have the desired effect. The same instance will be injected in both the BeanRequestFilter
and the BeanService
.
However, I think you may also get what you're looking for by injecting the ContainerRequestContext
directly into the BeanService
and forgetting about Bean
altogether.
@Stateless
public class BeanService {
@Context
ContainerRequestContext containerRequestContext;
public void doStuff() {
// <- get data from request
}
}
Upvotes: 0
Reputation: 1306
If you want the Bean
to be a kind of singleton using CDI see the @ApplicationScoped
annotation (in that case Bean
should be Sersializable
)
Or if you want the EJB BeanService
to be a singleton see the @Singleton
annotation
Upvotes: 0