De onde os objects @Context vêm

Eu tenho procurado em todo lugar, mas parece que não consigo encontrar uma resposta clara …

Qual é o mecanismo pelo qual um servidor (glassfish para meu problema) injeta objects reais que são anotados com @Context? Mais especificamente, se eu quisesse escrever uma aula que fizesse algo como:

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

então como eu faria isso? Onde é que o MyObject é instanciado, quem o faz e como?

Edit: eu vi coisas como o seguinte:

Usando @Context, @Provider e ContextResolver no JAX-RS

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

No entanto, isso não corresponde ao que eu vi, por exemplo, no construtor de org.neo4j.server.rest.web.RestfulGraphDatabase, que tem a seguinte assinatura:

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

Você pode escrever seu próprio provedor de injeção e conectá-lo em Jersey – veja SingletonTypeInjectableProvider e PerRequestTypeInjectableProvider – estenda uma dessas classs (dependendo do ciclo de vida desejado para o object injetável) e registre sua implementação como um provedor em seu aplicativo da web.

Por exemplo, algo como isto:

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

Para include o provedor em seu aplicativo da Web, você tem várias opções:

  1. se o seu aplicativo usar a verificação de caminho de class (ou verificação de pacote), apenas verifique se o provedor está no pacote correto / no caminho de class
  2. ou você pode simplesmente registrá-lo usando a input META-INF / services (inclua o arquivo META-INF / services / com.sun.jersey.spi.inject.InjectableProvider com o nome da sua class de provedor em seu conteúdo)

Eu acho que posso estar em algo … e se isso funcionar, Martin deve receber crédito parcial. 🙂

Parece que a class @Provider deve implementar a interface com.sun.jersey.spi.inject.Injectable . No entanto, não tenho certeza de que isso seja suficiente para que o @Context seja injetado. O que está faltando, é que temos que dizer ao object ResourceConfig do aplicativo da web sobre o @Provider. No contexto do que estou tentando fazer, e recebendo dicas do servidor neo4j, o restante do trabalho se resume a:

  • estendendo com.sun.jersey.spi.container.servlet.ServletContainer e substituindo o método de configuração:
 @Override protected void configure(WebConfig wc, ResourceConfig rc, WebApplication wa) { super.configure( wc, rc, wa ); Set singletons = rc.getSingletons(); singletons.add(new MyObjectProvider()); } 
  • especificando que este contêiner deve ser usado no descritor de implementação web.xml:
  JAX-RS Servlet Container com.blah.MyServletContainer  

Eu não acho que você pode usar @Context com um tipo definido pelo usuário como MyObject . É para injetar tipos que o jax-ws já entende. É mencionado aqui .

O Capítulo 5 da especificação JAX-RS apresenta todos os tipos Java JAX-RS padrão que podem ser usados ​​com @Context.

Você provavelmente quer usar algo como @FormParam ou @PathParam . Veja a seção 2.3 da especificação para uma descrição. Aqui está sua resposta, copiada daquela seção da especificação:

Em geral, o tipo Java do parâmetro method pode:

  1. Seja um tipo primitivo;
  2. Ter um construtor que aceite um único argumento String;
  3. Ter um método estático chamado valueOf ou fromString que aceite um único argumento String (consulte, por exemplo, Integer.valueOf (String) e java.util.UUID.fromString (String)); ou
  4. Seja List, Set ou SortedSet, onde T satisfaz 2 ou 3 acima. A coleção resultante é somente leitura.

Veja os capítulos 5-6 da especificação JAX-RS . Isso deve dizer tudo o que você precisa saber sobre isso.