0

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

所以这就是问题所在。当将实现IResourceStateControl的RatingResourceStateControl注入实现ICreateResource的RatingResourceStateBean时,在执行请求时会引发异常“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;
    }
}

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

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

最好的问候鲁迪

4

1 回答 1

0

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

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

于 2017-02-09T22:59:33.383 回答