我刚刚熟悉使用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方法都不会被调用.我在这做错了什么?
如果我使用Jersey 1.12,并且我有多个资源类,并且它们都需要访问一些共享上下文,那么注入依赖项的最佳方法是什么,无论是在资源类的构造函数中还是在处理程序方法中?我是否需要使用外部DI库,或者Jersey内置了什么?
也许Foos的资源看起来像这样:
package com.example.resource;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
@Path("/some/api/path/foo")
public class FooResource
{
@GET
@Produces("text/html")
public String getFoo(@QueryParam("id") String id)
{
Foo foo = /* get a Foo from some shared context based on id */
/* Process foo into a String */
}
}
Run Code Online (Sandbox Code Playgroud)
和酒吧:
package com.example.resource;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
@Path("/some/api/path/bar")
public class BarResource
{
@GET
@Produces("text/html")
public String getBar(@QueryParam("id") String id)
{
Bar bar = /* get a Bar from some shared …Run Code Online (Sandbox Code Playgroud) 我尝试实现自定义上下文注入,就像在这个答案中一样:
@Provider
public class DaoContextProvider extends SingletonTypeInjectableProvider<Context,Bar> {
public DaoContextProvider() {
super(Bar.class, new Bar("haha"));
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的控制器类,我想向女巫注入我的上下文:
@Path("foo")
public class Foo {
@Context
private Bar message;
@GET
public String index() {
return String.format("%s", message );
}
}
Run Code Online (Sandbox Code Playgroud)
但是响应消息为空。
我尝试将上下文提供者添加到单例中,如推荐的那样:
@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {
public ApplicationConfig() {
getSingletons().add(new DaoContextProvider());
}
//...
Run Code Online (Sandbox Code Playgroud)
但是然后我的工件甚至没有部署,并向我提供了此错误:
Artifact server:war exploded: java.io.IOException: com.sun.enterprise.admin.remote.RemoteFailureException: Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.UnsupportedOperationException. Please …Run Code Online (Sandbox Code Playgroud)