在 JAX-RS 中使用 @Context、@Provider 和 ContextResolver
我刚刚熟悉使用 JAX-RS 在 Java 中实现 REST Web 服务,但遇到了以下问题.我的资源类之一需要访问存储后端,该后端被抽象为 StorageEngine
接口.我想将当前的 StorageEngine
实例注入到服务于 REST 请求的资源类中,我认为这样做的一个好方法是使用 @Context
注释和适当的 ContextResolver
类.这是我目前所拥有的:
I'm just getting acquainted with implementing REST web services in Java using JAX-RS and I ran into the following problem. One of my resource classes requires access to a storage backend, which is abstracted away behind a StorageEngine
interface. I would like to inject the current StorageEngine
instance into the resource class serving the REST requests and I thought a nice way of doing this would be by using the @Context
annotation and an appropriate ContextResolver
class. This is what I have so far:
在 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.PackagesResourceConfig
自动发现提供程序和资源类,并根据日志获取 StorageEngineProvider
类很好(时间戳和不必要的东西故意遗漏):
I'm using com.sun.jersey.api.core.PackagesResourceConfig
to discover the providers and the resource classes automatically, and according to the logs, it picks up the StorageEngineProvider
class nicely (timestamps and unnecessary stuff left out intentionally):
INFO: Root resource classes found:
class MyResource
INFO: Provider classes found:
class StorageEngineProvider
但是,我的资源类中 storage
的值始终是 null
- 既不是 StorageEngineProvider
的构造函数,也不是它的 getContext
方法由 Jersey 调用,永远.我在这里做错了什么?
However, the value of storage
in my resource class is always null
- neither the constructor of StorageEngineProvider
nor its getContext
method is called by Jersey, ever. What am I doing wrong here?
推荐答案
我不认为有特定的 JAX-RS 方式来做你想做的事.最接近的做法是:
I don't think there's a JAX-RS specific way to do what you want. The closest would be to do:
@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 注释和 javax.ws.rs.ext.ContextResolver 确实适用于与 JAX-RS 相关的类型并支持 JAX-RS 提供程序.
However, I think the @javax.ws.rs.core.Context annotation and javax.ws.rs.ext.ContextResolver is really for types related to JAX-RS and supporting JAX-RS providers.
您可能希望在此处查找 Java 上下文和依赖注入 (JSR-299) 实现(应该在 Java EE 6 中可用)或其他依赖注入框架(例如 Google Guice)来帮助您.
You may want to look for Java Context and Dependency Injection (JSR-299) implementations (which should be available in Java EE 6) or other dependency injection frameworks such as Google Guice to help you here.
相关文章