我有一个带有JAX-RS,CDI和EJB的Web应用程序。在每个资源中,我注入一个无状态SessionBean,我的问题是是否可以将相同的实例注入JAX-RS和Stateless SesionBean的提供者。我试图从ContainerRequestFilter传递每个请求中的一些数据到Stateless SesionBean。所有EJB组件只能由jax rs resources访问。
示例:
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);
}
}
更新
更改Bean for Pojo,我的唯一目的是使用一个包含每个请求中的某个状态的类,并且可以在每个调用中传输,因为PojoResource到PojoService。我想以这种方式做到这一点,因为所有服务都会检索这些数据,我不希望将它作为参数传递给每个方法。
答案 0 :(得分:0)
如果您希望Bean
成为使用CDI的单身人士,请参阅@ApplicationScoped
annotation(在这种情况下Bean
应为Sersializable
)< / p>
或者,如果您希望EJB BeanService
成为单身,请参阅@Singleton
annotation
答案 1 :(得分:0)
这似乎是您的Bean
类本质上是请求作用域,因此将其更改为:
@RequestScoped
public class Bean {
...
}
应具有所需的效果。同一个实例将同时注入BeanRequestFilter
和BeanService
。
但是,我认为您可以通过将ContainerRequestContext
直接注入BeanService
并完全忘记Bean
来获得您正在寻找的内容。
@Stateless
public class BeanService {
@Context
ContainerRequestContext containerRequestContext;
public void doStuff() {
// <- get data from request
}
}
答案 2 :(得分:0)
在回答问题之前,Bean永远不应该更新。 bean的概念是提供服务并使用数据处理请求的概念。
也就是说,您当然可以将数据作为bean提供,但是数据需要在一个点上生成才能使用,而不是更新。
因此我会使用BeanRequestFilter
来生成bean,让BeanService
注入生成的bean。
尽管如此,我发现这是一个基于请求的数据?它是一个标题数据?,请求参数?然后我建议你在jax-rs资源类中使用jax-rs @QueryParam
或@HeaderParam
或@PathParam
或@FormParam
或@CookieParam
,然后将数据作为域对象参数提供给BeanService
,因此:
@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);
}
}