0
votes

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.

3

3 Answers

0
votes

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
   }
}
0
votes

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

0
votes

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);
    }
}