¿Cómo usar Jersey como implementación de JAX-RS sin web.xml?

He leído que desde java EE6 web.xml es opcional. Entonces, sin web.xml, ¿cómo puedo decirle al servidor de aplicaciones que use Jersey como implementación para la especificación JAX-RS?

Lo que @AlexNevidomsky escribió en su respuesta es correcto, en cuanto a cómo implementar la configuración de la aplicación sin web.xml; utiliza una anotación @ApplicationPath en una subclase de Application .

 @ApplicationPath("/api") public class AppConfig extends Application {} 

Para obtener más información sobre las opciones de implementación, consulte la especificación JAX-RS -> 2.3 Publicación -> 2.3.2 Servlet

O más comúnmente, con Jersey como implementación, extenderíamos ResourceConfig (que extiende la Application ).

 @ApplicationPath("api") public class AppConfig extends ResourceConfig { public AppConfig() { packages("package.to.scan"); } } 

Entonces, ¿cómo se implementa esto …

Lo primero es lo primero, no todos los servidores Java EE usan Jersey. De hecho, los únicos que conozco que usan Jersey son Glassfish y WebLogic. JBoss usa Resteasy. Tom EE usa CXF. WebSphere usa Apache Wink. Esos son los únicos en los que puedo pensar.

Así que supongo que la pregunta es “¿Cómo sabe el servidor cómo cargar la aplicación JAX-RS?”

Servlet 3.0 introdujo el mecanismo de pluggabilidad, que hace uso de un ServletContainerInitializer . Cómo funciona es que cuando se inicia el contenedor Servidor / Servlet, escanea jar para una carpeta META-INF/services con un archivo llamado javax.servlet.ServletContainerInitializer . Este archivo debe incluir uno o más nombres completos de implementaciones de ServletContainerInitializer .

Esta interfaz tiene solo un método

 void onStartup(java.util.Set> c, ServletContext ctx) 

El Set Será una lista de clases, que se @HandlesTypes los criterios en la anotación @HandlesTypes en la implementación de ServletContainerInitializer . Si miras la implementación de Jersey

 @HandlesTypes({ Path.class, Provider.class, Application.class, ApplicationPath.class }) public final class JerseyServletContainerInitializer implements ServletContainerInitializer { 

Debería observar algunas clases de anotación familiares, así como Application.class . Todas estas clases que coinciden con los criterios, durante el escaneo, se agregan al Set pasado al método onStartup .

Si escanea el rest del código fuente, verá que se está realizando todo el registro con todas esas clases.

Resteasy usa

 @HandlesTypes({Application.class, Path.class, Provider.class}) public class ResteasyServletInitializer implements ServletContainerInitializer 

No me meteré con los demás.

Alguna fuente que puedes mirar …

  • Código fuente JerseyServletContainerInitializer
  • ResteasyServletInitializer fuente de ResteasyServletInitializer
  • Especificaciones JAX-RS

No tiene que especificar nada en web.xml. Definir una clase de activador:

 @ApplicationPath("/rest") public class _JaxRsActivator extends javax.ws.rs.core.Application { static { //Check some system init on REST init. Config.initCheck(); } }