Grizzly e ServletContainerContext

Eu estou tentando se apossar de algum contexto injetado (por exemplo, Session ou HttpServletRequest) em um Servlet que eu escrevi, em execução no Grizzly, mas nada que eu pareço funcionar. Todo o processo parece parar prematuramente com o seguinte erro:

SEVERE: Missing dependency for field: javax.servlet.http.HttpServletRequest com.test.server.LolCat.hsr 

O servidor é simples, consiste em dois arquivos, o ponto de input estático (Main.java):

 package com.test.server; import java.io.IOException; import java.net.URI; import javax.ws.rs.core.UriBuilder; import org.glassfish.grizzly.http.server.HttpServer; import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; import com.sun.jersey.api.core.ClassNamesResourceConfig; import com.sun.jersey.api.core.ResourceConfig; public class Main { private static URI getBaseURI() { return UriBuilder.fromUri("http://localhost/").port(8080).build(); } public static final URI BASE_URI = getBaseURI(); public static void main(String[] args) throws IOException { ResourceConfig rc = new ClassNamesResourceConfig(LolCat.class); HttpServer httpServer = GrizzlyServerFactory.createHttpServer(BASE_URI, rc); System.in.read(); httpServer.stop(); } } 

e o serlvet (LolCat.java):

 package com.test.server; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Context; @Path(value = "/lol") public class LolCat { @Context HttpServletRequest hsr; @GET @Path(value="/cat") public String list() { return "meow"; } } 

Especificamente, é a linha de Contexto @ no arquivo de origem acima, que é a fonte e a solução para todos os meus problemas. Eu preciso disso, e de acordo com tudo que eu li sobre Jersey e Servlets, isso deve funcionar, mas infelizmente não funciona. Eu também tentei usar GrizzlyWebContainerFactory em vez do GrizzlyServerFactory, mas sem sucesso.

Para referência, o projeto é compilado com as seguintes dependencies:

  • org.glassfish.grizzly: grizzly-framework: jar: 2.2.21
  • org.glassfish.grizzly: grizzly-http: jar: 2.2.21
  • org.glassfish.grizzly: grizzly-http-servlet: jar: 2.2.21
  • org.glassfish.grizzly: grizzly-http-server: jar: 2.2.21
  • com.sun.jersey: jersey-server: jar: 1.17
  • com.sun.jersey: jersey-servlet: jar: 1.17
  • com.sun.jersey: jersey-core: jar: 1.17
  • javax.servlet: javax.servlet-api: jar: 2.5.0
  • com.sun.jersey: jersey-grizzly2: jar: 1.17
  • com.sun.jersey: jersey-grizzly2-servlet: jar: 1.17
  • asm: asm: jar: 3.3.1

Esta class principal funciona bem para mim:

 package com.test.server; import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; import java.io.IOException; import java.net.URI; import javax.ws.rs.core.UriBuilder; import com.sun.jersey.api.core.ClassNamesResourceConfig; import com.sun.jersey.spi.container.servlet.ServletContainer; import org.glassfish.grizzly.http.server.HttpHandler; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.http.server.Request; import org.glassfish.grizzly.http.server.Response; import org.glassfish.grizzly.servlet.ServletRegistration; import org.glassfish.grizzly.servlet.WebappContext; public class Main { private static final String JERSEY_SERVLET_CONTEXT_PATH = ""; private static URI getBaseURI() { return UriBuilder.fromUri("http://localhost").port(8080).path("/").build(); } public static final URI BASE_URI = getBaseURI(); public static void main(String[] args) throws IOException { // Create HttpServer and register dummy "not found" HttpHandler HttpServer httpServer = GrizzlyServerFactory.createHttpServer(BASE_URI, new HttpHandler() { @Override public void service(Request rqst, Response rspns) throws Exception { rspns.setStatus(404, "Not found"); rspns.getWriter().write("404: not found"); } }); // Initialize and register Jersey Servlet WebappContext context = new WebappContext("WebappContext", JERSEY_SERVLET_CONTEXT_PATH); ServletRegistration registration = context.addServlet("ServletContainer", ServletContainer.class); registration.setInitParameter(ServletContainer.RESOURCE_CONFIG_CLASS, ClassNamesResourceConfig.class.getName()); registration.setInitParameter(ClassNamesResourceConfig.PROPERTY_CLASSNAMES, LolCat.class.getName()); registration.addMapping("/*"); context.deploy(httpServer); System.in.read(); httpServer.stop(); } } 

Tente http://localhost:8080/lol/cat em seu navegador. Você pode alterar o JERSEY_SERVLET_CONTEXT_PATH para atualizar o caminho de contexto do Servlet.

De acordo com as explicações dos desenvolvedores – o Grizzly não é totalmente compatível com o JAX-RS 2.0, portanto, não haverá injeções / invólucros em contextos oficiais. Veja Jersey Bug-1960 Aplicável para Jersey + Grizzly versão 2.7+

Felizmente, existe uma maneira de injetar objects de solicitação / resposta do Grizzly. Meio complicado, mas funciona Amostra de código fornecida em um dos testes unitários de Jersey. Veja o teste de contêineres Jersey

Então, o fragment de código será:

 import javax.inject.Inject; import javax.inject.Provider; public someclass { @Inject private Provider grizzlyRequestProvider; public void method() { if (grizzlyRequestProvider != null) { Request httpRequest = grizzlyRequestProvider.get(); // Extract what you need } } } 

Funciona bem tanto para filtros quanto para methods de serviço

Você também pode registrar manualmente um ResourceContext

  HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(getBaseURI()); WebappContext context = new WebappContext("WebappContext", "/api"); ServletRegistration registration = context.addServlet("ServletContainer", new ServletContainer(config)); registration.addMapping("/*"); context.deploy(httpServer); 

Onde config é o contexto do seu recurso.