通过ResourceContext获取子资源时,将EJB插入到JAX-RS 2.0子资源中 [英] Inject EJB into JAX-RS 2.0 subresource when subresource is got via ResourceContext

查看:153
本文介绍了通过ResourceContext获取子资源时,将EJB插入到JAX-RS 2.0子资源中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Jersey 2.8与Glassfish 4.0。
我有一个资源定位器类,看起来像下面

  @Path(/)
@ ManagedBean
public class MyServiceLocator {
@Context
ResourceContext rc; // javax.ws.rs.container.ResourceContext

@EJB
private MyEJBHome myEJB ;

@ Inject // javax.inject.Inject
MySubService mss;

@Path(/ mysubservice)
public MySubService getMySubService(){
return rc.getResource(MySubService.class);
//也尝试返回rc.initResource(新的MySubService());
}
}

和一个子资源类是

  @ManagedBean 
public class MySubService {

@EJB
public MyEJBHome myEJB;

@Context
HttpHeaders头;

/ * @ Inject
private myEJBHome myEJB2; * /

@Path(/ mypath)
@GET
@Produces (MediaType.APPLICATION_JSON)
public Object doSomething(@Context SecurityContext securityContext){...}
}

beans.xml 文件放在META-INF和WEB-INF。



在MyServiceLocator类中, private MyEJBHome myEJB 注入成功。而 MySubService mss 对象注入成功,并注入EJB。



问题是当MySubService是通过ResourceContext得到的,EJB没有被注入到其中。



以前我使用Glassfish 3和Jersey 1.17与专有的ResourceContext,绝对相同的代码工作正常



我google了很多,读了很多类似(但有点不同)的问题,正如我理解非JAX-RS的东西(在我的情况下EJB)当通过ResorceContext获取子资源时,将被注入。是真的吗如果是,我可以如何工作?
一个可能的解决方案是将子资源对象注入到资源定位器类中,但是它们中有太多的东西似乎是非常难看的。



strong> EDIT 注入@Inject如果要创建一个绑定器,将ejb类绑定到ejb接口并注册该绑定。但我不想描述对数百个我的ejb的绑定。另外据了解,这是具体绑定的HK2系统,我不想链接到它。



不同的操作设置@Named注释,并尝试注入通过CDI没有帮助看来当通过ResourceContext获得子资源时,泽西只使用HK2,这就是为什么CDI无法做到这一点。这是正确的吗?

解决方案

我发现唯一适当的解决方案是创建自己的注释并注入提供者。

  @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface EJBInject {
String beanName();
}

@Provider
public class EjbInjectProvider implements InjectionResolver&EJBInject> {

@Override
public Object resolve(Injectee injectee,ServiceHandle<?> handle){

try {
String beanName = injectee.getParent ().getAnnotation(EJBInject.class).beanName();
返回新的InitialContext()。lookup(java:global / MyApp /+ beanName);
} catch(Exception e){
return null;
}
}

@Override
public boolean isConstructorParameterIndicator(){
return false;
}

@Override
public boolean isMethodParameterIndicator(){
return false;
}
}

然后ejb可以使用注释,如

@EJBInject(beanName =MyBean)
MyBeanEJBHome myBean;



在这种情况下,任何标准EJB注意MyBeanEJBHome可能需要正常工作。


I am using Jersey 2.8 with Glassfish 4.0. I have a resource locator class which looks like below

@Path("/")
@ManagedBean
public class MyServiceLocator {
    @Context
    ResourceContext rc;//javax.ws.rs.container.ResourceContext

    @EJB
    private MyEJBHome myEJB;

    @Inject//javax.inject.Inject
    MySubService mss;

    @Path("/mysubservice")
    public MySubService getMySubService() {
    return rc.getResource(MySubService.class);
    //also tried return rc.initResource(new MySubService());
    }
}

and a sub resource class which is

@ManagedBean
public class MySubService {

    @EJB
    public MyEJBHome myEJB;

    @Context
    HttpHeaders heads;

    /*@Inject
    private myEJBHome myEJB2;*/

    @Path("/mypath")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Object doSomething(@Context SecurityContext securityContext) {...}
}

beans.xml file is put to META-INF and WEB-INF.

In MyServiceLocator class private MyEJBHome myEJB is injected successfully. And MySubService mss object is injected successfully and with EJB injected into it.

The problem is that when MySubService is got via ResourceContext the EJB is not injected into it.

Previously i used Glassfish 3 and Jersey 1.17 with proprietary ResourceContext and absolutely the same code worked ok.

I googled a lot and read a lot of similar (but a bit different) questions and as i understood non JAX-RS stuff (EJB in my case) can't be injected when sub resource is got via ResorceContext. Is it true? If yes how can i work it around? The one possible solution is to inject sub resource objects to the resource locator class but there are too many of them and it seems to be very ugly.

EDIT Injection with @Inject works if to create a binder, bind ejb class to ejb interface and register that binder. But i don't want to describe binding for hundreds of my ejbs. Also as i understand it is specific binding fir HK2 system and i don't want to be linked to it.

Different actions with setting @Named annotations and trying to inject via CDI didn't help. It seems that when getting sub-resource via ResourceContext Jersey uses only HK2 and that's why CDI can't do it's work. Is that correct?

解决方案

The only appropriate solution i found was to create my own annotation and inject provider.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface EJBInject {
    String beanName();
}

@Provider
public class EjbInjectProvider implements InjectionResolver<EJBInject> {

    @Override
    public Object resolve(Injectee injectee, ServiceHandle<?> handle) {

        try {
            String beanName = injectee.getParent().getAnnotation(EJBInject.class).beanName();
            return new InitialContext().lookup("java:global/MyApp/" + beanName);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public boolean isConstructorParameterIndicator() {
        return false;
    }

    @Override
    public boolean isMethodParameterIndicator() {
        return false;
    }
}

Then ejb can be injected using that annotation like

@EJBInject(beanName="MyBean") MyBeanEJBHome myBean;

In such case any standard EJB injections which MyBeanEJBHome might need work correctly, too.

这篇关于通过ResourceContext获取子资源时,将EJB插入到JAX-RS 2.0子资源中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆