14

我一直在到处寻找,但似乎找不到明确的答案......

服务器(我的问题是 glassfish)注入带有@Context 注释的实际对象的机制是什么?更具体地说,如果我想编写一个执行以下操作的类:

@Path("/")
public class MyResource {
  @GET
  public String doSomething(@Context MyObject obj) {
    // ...
  }
}

那我该怎么做呢?MyObject 在哪里被实例化,谁做的,如何做的?

编辑:我见过类似以下的东西:

在 JAX-RS 中使用 @Context、@Provider 和 ContextResolver

http://jersey.576304.n2.nabble.com/ContextResolver-confusion-td5654154.html

但是,这与我所看到的不符,例如在 org.neo4j.server.rest.web.RestfulGraphDatabase 的构造函数中,它具有以下签名:

public RestfulGraphDatabase(
  @Context UriInfo uriInfo,
  @Context Database database,
  @Context InputFormat input,
  @Context OutputFormat output,
  @Context LeaseManager leaseManager )
4

4 回答 4

8

您可以编写自己的注入提供程序并将其插入 Jersey - 查看SingletonTypeInjectableProviderPerRequestTypeInjectableProvider - 扩展这些类之一(取决于您想要的可注入对象的生命周期)并将您的实现注册为 Web 应用程序中的提供程序。

例如,像这样:

@Provider
public class MyObjectProvider extends SingletonTypeInjectableProvider<Context, MyObject> {
    public MyObjectProvider() {
        // binds MyObject.class to a single MyObject instance
        // i.e. the instance of MyObject created bellow will be injected if you use
        // @Context MyObject myObject
        super(MyObject.class, new MyObject());
    }
}

要将提供程序包含在您的 Web 应用程序中,您有多种选择:

  1. 如果您的应用程序使用类路径扫描(或包扫描),只需确保提供程序位于正确的包中/在类路径上
  2. 或者您可以简单地使用 META-INF/services 条目注册它(添加 META-INF/services/com.sun.jersey.spi.inject.InjectableProvider 文件,其中包含您的提供程序类的名称)
于 2012-06-05T14:47:25.517 回答
3

我想我可能正在做某事……如果这可行,马丁应该得到部分荣誉。:)

看来@Provider 类必须实现com.sun.jersey.spi.inject.Injectable<T>接口。但是,我不确定这是否足以实际注入@Context。缺少的是,我们必须告诉 Web 应用程序的 ResourceConfig 对象有关 @Provider 的信息。在我正在尝试做的事情的背景下,并从 neo4j-server 获得提示,剩下的工作归结为:

  • 扩展 com.sun.jersey.spi.container.servlet.ServletContainer,并覆盖 configure 方法:
@Override
protected void configure(WebConfig wc, ResourceConfig rc, WebApplication wa)
{
  super.configure( wc, rc, wa );
  Set<Object> singletons = rc.getSingletons();
  singletons.add(new MyObjectProvider());
}
  • 指定必须在 web.xml 部署描述符中使用此容器:
<servlet>
  <servlet-name>JAX-RS Servlet Container</servlet-name>
  <servlet-class>com.blah.MyServletContainer</servlet-class>
</servlet>
于 2012-06-05T15:41:48.780 回答
0

我认为您不能使用@Context用户定义的类型,例如MyObject. 它用于注入 jax-ws 已经理解的类型。这里提到了。

JAX-RS 规范的第 5 章介绍了可以与 @Context 一起使用的所有标准 JAX-RS Java 类型。

您可能想使用类似@FormParamor的东西@PathParam。有关说明,请参阅规范的第 2.3 节。这是您的答案,从规范的该部分复制:

通常,方法参数的 Java 类型可能:

  1. 是原始类型;
  2. 有一个接受单个 String 参数的构造函数;
  3. 有一个名为 valueOf 或 fromString 的静态方法,它接受单个 String 参数(例如,参见 Integer.valueOf(String) 和 java.util.UUID.fromString(String));或者
  4. 是 List、Set 或 SortedSet,其中 T 满足上述 2 或 3。生成的集合是只读的。
于 2012-06-05T13:25:47.240 回答
-1

请参阅JAX-RS 规范的第 5-6 章。这应该告诉你你需要知道的一切。

于 2012-06-05T13:24:14.870 回答