Jax-rs,JavaEE7,Java8:在 SystemInjecteeImpl 中没有可用于注入的对象

Jax-rs, JavaEE7, Java8: There was no object available for injection at SystemInjecteeImpl

我是一家中型软件公司的软件工程师,有一段时间在休息框架上工作。他们是关于 Java8 接口中默认方法的酷东西。所以我决定使用这个默认行为来实现 CRUD 功能,每个功能在它自己的界面中分开(ICreateResource)。在 CRUD 方法中执行的逻辑由一个额外的 class 提供,它也被声明为一个接口 IResourceStateControl.

问题来了。将实现 IResourceStateControlRatingResourceStateControl 注入实现 ICreateResourceRatingResourceStateBean 时] 执行请求时出现异常"There was no object available for injection at SystemInjecteeImpl"。

public interface ICreateResource
{
    IResourceStateControl getResourceStateControl();

    @POST
    @Consumes(APPLICATION_JSON)
    @Produces(COLLECTION_JSON)
    default Response post(@Context UriInfo uriInfo, ApplicationState representation)
    {
        try
        {
            Collection collection = getResourceStateControl().post(uriInfo, representation);
            return Response.created(collection.getHref().get()).entity(collection).build();
        }
        catch (Exception exception)
        {
            throw new WebApplicationException(exception.getMessage(), exception, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }
}

@Dependent
public class RatingResourceStateControl implements IResourceStateControl
{

    @Override
    public Collection get(UriInfo uriInfo, int start, int size, long parentResourceId)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Collection get(UriInfo uriInfo, long id)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Collection post(UriInfo uriInfo, ApplicationState representation)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Boolean delete(long id)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Collection put(UriInfo uriInfo, long id, ApplicationState representation)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Collection patch(UriInfo uriInfo, long id, ApplicationState representation)
    {
        // TODO Auto-generated method stub
        return null;
    }
}
@Stateless
@Path("/" + RATINGS_PATH)
public class RatingResourceStateBean implements ICreateResource
{
    @Inject
    private RatingResourceStateControl ratingResourceControl;

    @Override
    public IResourceStateControl getResourceStateControl()
    {
        return ratingResourceControl;
    }
}

但是当使用抽象 class 来提供功能时一切正常。

public abstract class AbstractResourceState
{
    protected abstract IResourceStateControl getResourceStateControl();

    @Context
    private UriInfo uriInfo;
    @Context
    private HttpServletRequest httpServletRequest;

    @POST
    @Consumes(APPLICATION_JSON)
    @Produces(COLLECTION_JSON)
    public Response post(ApplicationState representation)
    {
        try
        {
            Collection collection = getResourceStateControl().post(uriInfo, representation);
            return Response.created(collection.getHref().get()).entity(collection).build();
        }
        catch (Exception exception)
        {
            throw new WebApplicationException(exception.getMessage(), exception, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }
}

@Stateless
@Path("/" + RATINGS_PATH)
public class RatingResourceStateBean extends AbstractResourceState
{
    @Inject
    private RatingResourceStateControl ratingResourceControl;

    @Override
    protected IResourceStateControl getResourceStateControl()
    {
        return ratingResourceControl;
    }
}

api 正在使用抽象的 class 方法,但是通过简单地实现适当的接口来控制可用的 CRUD 方法会非常好。一切都部署在 payara 4.1.1 应用服务器上。

最好的问候 鲁迪

您正在尝试将 JAX-RS 资源 @Context UriInfo uriInfo 注入 ICreateResource.post,这是默认方法。由于 JAX-RS API 是基于 Java 7 的,因此您需要小心使用默认方法,因为规范没有说明它们。这完全取决于反射 API 如何公开有关默认方法的信息。

问题也可能是您覆盖默认方法,但没有复制@Context注释。当服务器扫描 class 时,它不会在方法签名中看到任何 @Context 注释(就好像默认方法不存在一样)。