¿Es posible configurar una aplicación JAX-RS usando solo anotaciones? (usando Servlet 3.0 y JAX-RS Jersey 1.1.0)
Lo intenté y no tuve suerte. web.xml
Parece necesario usar algunos .
Configuración A (funcionando, pero tiene configuración web.xml)
web.xml
...
<servlet>
<servlet-name>org.foo.rest.MyApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>org.foo.rest.MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
...
Java
@ApplicationPath("/")
public class MyApplication extends Application {
...
}
Configuración B (no funciona, se lanzó una excepción)
@ApplicationPath("/")
@WebServlet("/*") // <--
public class MyApplication extends Application {
...
}
Este último parece insistir en que la Aplicación será una subclase de Servlet (la excepción no deja conjeturas)
java.lang.ClassCastException: org.foo.rest.MyApplication cannot be cast to javax.servlet.Servlet
Preguntas
¿Por qué funcionó la definición web.xml pero no la anotación? ¿Cual es la diferencia?
¿Hay alguna manera de que funcione, por ejemplo, tener una aplicación JAX-RS sin web.xml?
java
jakarta-ee
jax-rs
servlet-3.0
Eran Medan
fuente
fuente
Respuestas:
** POR FAVOR LEA SI UTILIZA TOMCAT O JETTY! **
La respuesta aceptada hace el trabajo, pero sólo si la aplicación Web se implementa en un servidor de aplicación como Glassfish o JBoss, y posiblemente contenedores de servlets con extensiones de EE como TomEE. Que no funciona en contenedores de servlets estándar como Tomcat, que estoy seguro que la mayoría de las personas que buscan una solución a este problema que desee utilizar.
Si está utilizando una instalación estándar de Tomcat (o algún otro contenedor de servlets), debe incluir una implementación REST ya que Tomcat no viene con una. Si está usando Maven, agregue esto a la
dependencies
sección:<dependencies> <dependency> <groupId>org.glassfish.jersey.bundles</groupId> <artifactId>jaxrs-ri</artifactId> <version>2.13</version> </dependency> ... </dependencies>
Luego, simplemente agregue una clase de configuración de la aplicación a su proyecto. Si no tiene ninguna necesidad de configuración especial además de establecer la ruta de contexto para los demás servicios, la clase puede estar vacía. Una vez que se agrega esta clase, no es necesario configurar nada en
web.xml
(o tener uno):package com.domain.mypackage; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("rest") // set the path to REST web services public class ApplicationConfig extends Application {}
Después de esto, declarar sus servicios web es sencillo usando las anotaciones JAX-RS estándar en sus clases de Java:
package com.domain.mypackage; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.GET; import javax.ws.rs.MatrixParam; import javax.ws.rs.Path; // It's good practice to include a version number in the path so you can have // multiple versions deployed at once. That way consumers don't need to upgrade // right away if things are working for them. @Path("calc/1.0") public class CalculatorV1_0 { @GET @Consumes("text/plain") @Produces("text/plain") @Path("addTwoNumbers") public String add(@MatrixParam("firstNumber") int n1, @MatrixParam("secondNumber") int n2) { return String.valueOf(n1 + n2); } }
Esto debería ser todo lo que necesita. Si su instalación de Tomcat se está ejecutando localmente en el puerto 8080 e implementa su archivo WAR en el contexto
myContext
, vaya a ...... debería producir el resultado esperado (5).
fuente
web.xml
no está presente. En supom.xml
, en "Crecimiento> plugins", ADD (si no está ya allí):<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>2.3</version><configuration><failOnMissingWebXml>false</failOnMissingWebXml></configuration></plugin>
.<failOnMissingWebXml>false</failOnMissingWebXml>
opción.Application
y le agregue la@ApplicationPath
anotación. La clase puede estar vacía, pero debe estar allí.jersey-container-servlet
, sin eliminar toda lajaxrs-ri
dependencia. Por ejemplo, en mi caso fue'org.glassfish.jersey.core:jersey-server:2.18'
+'org.glassfish.jersey.containers:jersey-container-servlet:2.18'
.Parece que todo lo que necesitaba hacer es esto (Servlet 3.0 y superior)
import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("/*") public class MyApplication extends Application { ... }
Y aparentemente no se necesitaba ninguna configuración web.xml (probado en Tomcat 7)
fuente
El Capítulo 2 de la especificación JAX-RS: Java ™ API para RESTful Web Services describe el proceso de publicación de una aplicación JAX-RS en un entorno Servlet (sección 2.3.2 Servlet en la especificación).
Tenga en cuenta que solo se recomienda el entorno Servlet 3 (sección 2.3.2 Servlet, página 6):
En resumen, si desea utilizar un enfoque no-web.xml, es posible con una implementación personalizada de javax.ws.rs.core.Application que registra los recursos del servicio RESTful con la anotación javax.ws.rs.ApplicationPath .
@ApplicationPath("/rest")
Aunque preguntó específicamente sobre Jersey, también puede leer el artículo Implementación de servicios RESTful con JAX-RS y WebSphere 8.5 Liberty Profile en el que describí el proceso de publicación no-web.xml para WebSphere Liberty Profile (con Apache Wink como la implementación de JAX-RS).
fuente
@ApplicationPath("")
para tener mis servicios REST en la raíz (en relación con la raíz de contexto de la aplicación web) en JBoss EAP 7. No tengobeans.xml
niweb.xml
.Necesita configurar las dependencias correctas en pom.xml
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> </dependency>
Más detalles aquí: ejemplo de inicio para jax-rs
fuente
<failOnMissingWebXml>
Las dependencias mencionadas anteriormente no funcionaron para mí. De la guía del usuario de Jersey:
https://jersey.github.io/documentation/latest/deployment.html#deployment.servlet.3
fuente
Como señaló @ Eran-Medan, JBoss EAP 7.1 (tenga en cuenta que sin una aplicación web, por lo que no hay servlet, lo estaba haciendo en un proyecto EJB 3.2) tuve que agregar el atributo "valor" como tal, estaba obteniendo una excepción que el El atributo de valor era obligatorio.
Esto funcionó para mi
@ApplicationPath(value="/*") public class MyApplication extends Application { private Set singletons = new HashSet(); public MyApplication() { singletons.add(new MyService()); } ... }
Seguimiento de pila
Caused by: java.lang.annotation.IncompleteAnnotationException: javax.ws.rs.ApplicationPath missing element value at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:80) at com.sun.proxy.$Proxy141.value(Unknown Source) ... 21 more
fuente