java jersey jax-rs cdi grizzly

¿Cómo habilitar la inyección de CDI en el servicio web(jaxrs/jersey) en java se running grizzly?



jax-rs (3)

La respuesta seleccionada data de hace un tiempo. No es práctico declarar cada encuadernación en una carpeta personalizada HK2. Solo tuve que agregar una dependencia. Aunque fue diseñado para Glassfish, se adapta perfectamente a otros contenedores. Estoy usando Tomcat / Grizzly.

<dependency> <groupId>org.glassfish.jersey.containers.glassfish</groupId> <artifactId>jersey-gf-cdi</artifactId> <version>2.14</version> </dependency>

Aquí hay un ejemplo con JerseyTest (el mismo principio si lo ejecuta desde un método principal). Solo tuve que declarar una dependencia de weld-se y declarar un contenedor de soldadura antes de crear mis recursos, como también lo hizo, y funciona de la caja.

public class GrizzlyTest extends JerseyTest { private Weld weld; private WeldContainer container; @Override protected Application configure() { weld = new Weld(); container = weld.initialize(); return new ResourceConfig(MyResource.class); } @Test public void test() { System.out.println(target("myresource").request().get(String.class)); } @After public void after() { weld.shutdown(); } }

¿Cómo permito la inyección de CDI de recursos en recursos de servicio web relajantes? Me estoy ejecutando en Java estándar usando weld 2 (cdi), jersey (jaxrs) y grizzly (servidor web). Aquí está mi recurso web simple:

import training.student.StudentRepository; import javax.inject.Inject; import javax.ws.rs.*; @Path("student") public class StudentWebResource { @Inject private StudentRepository studentRepository; @GET @Path("count") @Produces(MediaType.TEXT_PLAIN) public Integer getCount() { return studentRepository.studentCount(); } }

Y así es como he soldado mi sencillo servidor web:

public class Main { public static void main(String[] args) throws Exception { startCdiApplication(); } public static void startCdiApplication() throws Exception { Weld weld = new Weld(); try { WeldContainer container = weld.initialize(); Application application = container.instance().select(WebServer.class).get(); application.run(); } finally { weld.shutdown(); } } }

Y el código que sospecho tendrá que ser modificado para informar a Jersey que use soldadura para la resolución de inyección de CDI:

... import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; public class WebServer implements Application { /* * startup the grizzly http server to make available the restful web services */ private void startWebServer() throws IOException, InterruptedException { final ResourceConfig resourceConfig = new ResourceConfig().packages("training.webservice").register(new JacksonFeature()); final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(getBaseUri(), resourceConfig); server.start(); Thread.currentThread().join(); } ... @Override public void run() throws IOException, InterruptedException { startWebServer(); } }


Dado que al menos Weld 2.2.0.Final no hay necesidad de meter la pata con HK2 Binder.

Como la documentación oficial de Weld indica que solo necesita registrar org.jboss.weld.environment.servlet.Listener . Código cortado del documento:

public class Main { public static void main(String[] args) throws ServletException, LifecycleException { Tomcat tomcat = new Tomcat(); Context ctx = tomcat.addContext("/", new File("src/main/resources").getAbsolutePath()); Tomcat.addServlet(ctx, "hello", HelloWorldServlet.class.getName()); ctx.addServletMapping("/*", "hello"); ctx.addApplicationListener(Listener.class.getName()); tomcat.start(); tomcat.getServer().await(); } public static class HelloWorldServlet extends HttpServlet { @Inject private BeanManager manager; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/plain"); resp.getWriter().append("Hello from " + manager); } } }

El oyente de servlet anterior gestiona todo el ciclo de vida del contenedor de soldadura. Entonces no hay necesidad de:

Weld weld = new Weld(); WeldContainer container = weld.initialize();

ACTUALIZACIÓN Como @EdMelo señaló, el servidor HTTP Grizzly no es un contenedor de servlets totalmente compatible. No lo sabía, gracias por esta pista. Entonces no estoy seguro, si mi respuesta todavía se aplica aquí.


Después de ver esta publicación , implementé la siguiente solución. No estoy seguro de si es la mejor ruta, pero funcionó.

Creé un Binder hk2 y registré el Binder:

public class WebServiceBinder extends AbstractBinder { @Override protected void configure() { BeanManager bm = getBeanManager(); bind(getBean(bm, StudentRepository.class)) .to(StudentRepository.class); } private BeanManager getBeanManager() { // is there a better way to get the bean manager? return new Weld().getBeanManager(); } private <T> T getBean(BeanManager bm, Class<T> clazz) { Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next(); CreationalContext<T> ctx = bm.createCreationalContext(bean); return (T) bm.getReference(bean, clazz, ctx); } }

Luego modificó la creación de instancias ResourceConfig desde arriba a:

final ResourceConfig resourceConfig = new ResourceConfig() .packages("training.webservice") .register(new JacksonFeature()) .register(new WebServiceBinder());