在JAX-RS中使用@ Context,@ Extider和ContextResolver

Tam*_*más 30 java jax-rs jersey

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

MyResource.java:

class MyResource {
    @Context StorageEngine storage;
    [...]
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用com.sun.jersey.api.core.PackagesResourceConfig自动发现提供程序和资源类,并根据日志,它StorageEngineProvider很好地获取类(时间戳和故意遗漏的不必要的东西):

INFO: Root resource classes found:
    class MyResource
INFO: Provider classes found:
    class StorageEngineProvider
Run Code Online (Sandbox Code Playgroud)

但是,storage我的资源类中的值总是如此null- Jersey的调用器StorageEngineProvider及其getContext方法都不会被调用.我在这做错了什么?

Bry*_*Luk 19

我不认为有一种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);
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

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

您可能希望查找Java上下文和依赖注入(JSR-299)实现(应该在Java EE 6中可用)或其他依赖注入框架(如Google Guice)来帮助您.

  • FWIW你也可以稍微缩短:@Context ContextResolver <StorageEngine> storageEngineResolver; (2认同)

Cha*_*ase 13

实现InjectableProvider.最有可能通过扩展PerRequestTypeInjectableProvider或SingletonTypeInjectableProvider.

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

让你有:

@Context StorageEngine storage;
Run Code Online (Sandbox Code Playgroud)

  • 特定于泽西岛,但是一个很好的建议.CXF与[`ContextProvider`](http://sberyozkin.blogspot.co.uk/2012/03/custom-jax-rs-contexts-in-cxf-260.html)类似. (2认同)