Jax-rs初始化子资源没有可用于注入的对象

时间:2016-03-29 04:32:58

标签: jax-rs javabeans glassfish-4 java-ee-7

我有一个子资源类,必须使用路径中的参数进行初始化,并且还包含对必须注入的EJB的引用。

资源类:

@Path("widgets")
public class MasterResource{
    @Inject
    WidgetBean widgets;

    @Context
    ResourceContext rc;

    @Path("{year}")
    public WidgetArchives wArchives(@PathParam("year") String year){
        return rc.initResource(new WidgetArchiveResource(year));
    }
}

子资源类

public class WidgetArchiveResource{
    @Inject
    WidgetBean widgets;

    public WidgetArchiveResource(String year){
        ....code
    }

    @GET
    public String doGet(){
        ....code using WidgetBean
    }
}

当我调用年份时,我看到以下错误:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=WidgetBean,parent=WidgetArchiveResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,542790913)

我是Java EE的新手。我做错了什么?

1 个答案:

答案 0 :(得分:2)

方法rc.initResource只有在需要向资源中注入一些依赖项时才有意义(例如,由@Inject注释)。这是一种将依赖项注入bean的JAX-RS特定方法。它在完全JavaEE环境中被弃用,其中注入依赖项的首选方法是通过CDI。 rc.initResource不会注入所有CDI bean(例如@EJB可以工作,但@Inject不能)。

因此,在JavaEE中,执行您想要实现的目标的首选方法是将WidgetArchiveResource注入父MasterResource。 CDI bean必须具有不带参数的构造函数,但您可以使用setter传递year。如果您将主资源放在请求范围内,则会为每个请求重新创建它,使其对并发请求安全:

@Path("widgets")
@RequestScoped
public class MasterResource{
    @Inject
    Instance<WidgetArchiveResource> waResources;

    @Path("{year}")
    public WidgetArchives wArchives(@PathParam("year") String year){
        WidgetArchiveResource waResource = waResources.get();
        waResource.setYear(year);
        return waResource;
    }
}

此外,您应该在带有bean-discovery-mode="all"的WEB-INF文件夹中包含beans.xml,或者在WidgetArchiveResource上明确添加相关范围以使其符合CDI条件:

@Dependent
public class WidgetArchiveResource {
    public WidgetArchiveResource() {} // optional no arg constructor
}