在 JAX-RS 中使用@Context、@Provider和上下文解析器

2022-09-01 10:54:12

我刚刚熟悉了使用 JAX-RS 在 Java 中实现 REST Web 服务,我遇到了以下问题。我的一个资源类需要访问存储后端,该后端抽象出在接口后面。我想将当前实例注入到为REST请求提供服务的资源类中,我认为这样做的一个好方法是使用注释和适当的类。这是我到目前为止所拥有的:StorageEngineStorageEngine@ContextContextResolver

在:MyResource.java

class MyResource {
    @Context StorageEngine storage;
    [...]
}

在:StorageEngineProvider.java

@Provider
class StorageEngineProvider implements ContextResolver<StorageEngine> {
    private StorageEngine storage = new InMemoryStorageEngine();

    public StorageEngine getContext(Class<?> type) {
        if (type.equals(StorageEngine.class))
            return storage;
        return null;
    }
}

我使用自动发现提供程序和资源类,并且根据日志,它可以很好地拾取类(时间戳和不必要的东西故意省略):com.sun.jersey.api.core.PackagesResourceConfigStorageEngineProvider

INFO: Root resource classes found:
    class MyResource
INFO: Provider classes found:
    class StorageEngineProvider

但是,在我的资源类中,的值始终是 - Jersey 永远不会调用 的构造函数及其方法。我在这里做错了什么?storagenullStorageEngineProvidergetContext


答案 1

我不认为有JAX-RS特定的方式来做你想做的事情。最接近的方法是:

@Path("/something/")
class MyResource {
    @Context
    javax.ws.rs.ext.Providers providers;

    @GET
    public Response get() {
        ContextResolver<StorageEngine> resolver = providers.getContextResolver(StorageEngine.class, MediaType.WILDCARD_TYPE);
        StorageEngine engine = resolver.get(StorageEngine.class);
        ...
    }
}

但是,我认为@javax.ws.rs.core.Context annotation 和 javax.ws.rs.ext.ContextResolver 实际上适用于与 JAX-RS 相关的类型并支持 JAX-RS 提供程序。

您可能希望查找 Java Context and Dependency Injection (JSR-299) 实现(应该在 Java EE 6 中可用)或其他依赖注入框架(如 Google Guice)来帮助您。


答案 2

实现可注射提供程序。最有可能通过扩展PerRequestTypeInjectableProvider或SingletonTypeInjectableProvider。

@Provider
public class StorageEngineResolver extends SingletonTypeInjectableProvider<Context, StorageEngine>{
    public MyContextResolver() {
        super(StorageEngine.class, new InMemoryStorageEngine());
    }
}

会让你有:

@Context StorageEngine storage;

推荐