java @Context 对象从何而来

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10897933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:01:26  来源:igfitidea点击:

Where do @Context objects come from

javaglassfishjerseyjax-rs

提问by Kricket

I've been searching everywhere, but can't seem to find a clear answer...

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

What is the mechanism whereby a server (glassfish for my problem) injects actual objets that are annotated with @Context? More specifically, if I wanted to write a class that did something like:

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

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

then how would I do it? Where is it that the MyObject is instanciated, who does it, and how?

那我该怎么做呢?MyObject 在哪里实例化,由谁实例化,以及如何实例化?

Edit: I've seen stuff like the following:

编辑:我见过如下内容:

Using @Context, @Provider and ContextResolver in JAX-RS

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

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

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

However, this doesn't square with what I've seen, e.g. in the constructor of org.neo4j.server.rest.web.RestfulGraphDatabase, which has the following signature:

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

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

采纳答案by Martin Matula

You can write your own injection provider and plug that into Jersey - look at SingletonTypeInjectableProviderand PerRequestTypeInjectableProvider- extend one of these classes (depending on the lifecycle you want for the injectable object) and register your implementation as a provider in your web app.

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

For example, something like this:

例如,这样的事情:

@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());
    }
}

To include the provider in your web app you have several options:

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

  1. if your app uses classpath scanning (or package scanning) just make sure the provider is in the right package / on the classpath
  2. or you can simply register it using META-INF/services entry (add META-INF/services/com.sun.jersey.spi.inject.InjectableProvider file having the name of your provider class in it's contents)
  1. 如果您的应用程序使用类路径扫描(或包扫描),请确保提供程序位于正确的包中/在类路径上
  2. 或者您可以简单地使用 META-INF/services 条目注册它(添加 META-INF/services/com.sun.jersey.spi.inject.InjectableProvider 文件,其中包含您的提供者类的名称)

回答by Kricket

I think I may be on to something...and if this works, Martin should get partial credit. :)

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

It appears that the @Provider class must implement the com.sun.jersey.spi.inject.Injectable<T>interface. However, I'm not sure that this is enough to actually have the @Context be injected. What's missing, is that we have to tell the ResourceConfig object of the web app about the @Provider. In the context of what I'm trying to do, and taking hints from neo4j-server, the remaining work boils down to:

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

  • extending com.sun.jersey.spi.container.servlet.ServletContainer, and overriding the configure method:
  • 扩展 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());
}
@Override
protected void configure(WebConfig wc, ResourceConfig rc, WebApplication wa)
{
  super.configure( wc, rc, wa );
  Set<Object> singletons = rc.getSingletons();
  singletons.add(new MyObjectProvider());
}
  • specifying that this container must be used in the web.xml deployment descriptor:
  • 指定必须在 web.xml 部署描述符中使用此容器:
<servlet>
  <servlet-name>JAX-RS Servlet Container</servlet-name>
  <servlet-class>com.blah.MyServletContainer</servlet-class>
</servlet>
<servlet>
  <servlet-name>JAX-RS Servlet Container</servlet-name>
  <servlet-class>com.blah.MyServletContainer</servlet-class>
</servlet>

回答by John Watts

I don't think you can use @Contextwith a user-defined type like MyObject. It is for injecting types that jax-ws already understands. It is mentioned here.

我不认为你可以使用@ContextMyObject. 它用于注入 jax-ws 已经理解的类型。这里提到

Chapter 5of the JAX-RS specification presents all the standard JAX-RS Java types that may be used with @Context.

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

You probably want to use something like @FormParamor @PathParaminstead. See section 2.3of the spec for a description. Here is your answer, copied from that section of the spec:

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

In general the Java type of the method parameter may:

  1. Be a primitive type;
  2. Have a constructor that accepts a single String argument;
  3. Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String) and java.util.UUID.fromString(String)); or
  4. Be List, Set or SortedSet, where T satisfies 2 or 3 above. The resulting collection is read-only.

一般来说,方法参数的 Java 类型可能:

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

回答by Ryan Stewart

See chapters 5-6 of the JAX-RS spec. That should tell you everything you need to know about it.

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