Est-il possible de configurer une application JAX-RS en utilisant uniquement des annotations? (en utilisant Servlet 3.0 et JAX-RS Jersey 1.1.0)
J’ai essayé et n’ai pas eu de chance. L’utilisation de web.xml
semble nécessaire.
Configuration A (fonctionne, mais a la configuration web.xml)
web.xml
... org.foo.rest.MyApplication org.foo.rest.MyApplication /* ...
Java
@ApplicationPath("/") public class MyApplication extends Application { ... }
Configuration B (ne fonctionne pas, exception levée)
@ApplicationPath("/") @WebServlet("/*") // <-- public class MyApplication extends Application { ... }
Ce dernier semble insister sur le fait que l’application sera une sous-classe de Servlet (l’exception ne laisse aucune conjecture)
java.lang.ClassCastException: org.foo.rest.MyApplication cannot be cast to javax.servlet.Servlet
Des questions
Pourquoi la définition web.xml a-t-elle fonctionné mais pas l’annotation? Quelle est la différence?
Est-il possible de le faire fonctionner, par exemple avoir une application JAX-RS sans web.xml?
** VEUILLEZ LIRE SI VOUS UTILISEZ TOMCAT OU JETTY! **
La réponse acceptée fonctionne, mais uniquement si l’application Web est déployée sur un serveur d’applications comme Glassfish ou Wildfly, et éventuellement sur des conteneurs de servlets dotés d’extensions EE telles que TomEE. Il ne fonctionne pas sur les conteneurs de servlets standard tels que Tomcat, dont je suis sûr que la plupart des personnes recherchant une solution ici veulent utiliser.
Si vous utilisez une installation standard de Tomcat (ou un autre conteneur de servlets), vous devez inclure une implémentation REST car Tomcat n’en contient pas. Si vous utilisez Maven, ajoutez-le à la section dependencies
:
org.glassfish.jersey.bundles jaxrs-ri 2.13 ...
Ajoutez simplement une classe de configuration d’application à votre projet. Si vous n’avez pas besoin de configuration particulière en dehors de la définition du chemin de contexte pour les services restants, la classe peut être vide. Une fois cette classe ajoutée, vous n’avez pas besoin de configurer quoi que ce soit dans web.xml
(ou d’en avoir une):
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 {}
Après cela, déclarer vos services Web est simple en utilisant les annotations JAX-RS standard dans vos classes Java:
package com.domain.mypackage; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.GET; import javax.ws.rs.MasortingxParam; 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 Ssortingng add(@MasortingxParam("firstNumber") int n1, @MasortingxParam("secondNumber") int n2) { return Ssortingng.valueOf(n1 + n2); } }
Cela devrait être tout ce dont vous avez besoin. Si votre installation Tomcat est exécutée localement sur le port 8080 et que vous déployez votre fichier WAR dans le contexte myContext
, allez à …
http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
… devrait produire le résultat attendu (5).
Il semble que tout ce que je devais faire est ceci (Servlet 3.0 et supérieur)
@ApplicationPath("/*") public class MyApplication extends Application { ... }
Et aucune configuration web.xml n’était apparemment nécessaire (essayé sur Tomcat 7)
Le chapitre 2 de la spécification JAX-RS: Java ™ pour les services Web RESTful décrit le processus de publication d’une application JAX-RS dans un environnement Servlet (section 2.3.2 Servlet dans la spécification).
Veuillez noter que l’environnement Servlet 3 est recommandé uniquement (section 2.3.2 Servlet, page 6):
Il est RECOMMANDÉ que les implémentations prennent en charge le mécanisme de pluggability Framework Servlet 3 pour permettre la portabilité entre les conteneurs et se prévaloir des fonctions d’parsing de classe fournies par le conteneur.
En bref, si vous souhaitez utiliser une approche no-web.xml, il est possible avec une implémentation personnalisée de javax.ws.rs.core.Application qui enregistre les ressources de service RESTful avec l’annotation javax.ws.rs.ApplicationPath .
@ApplicationPath("/rest")
Bien que vous ayez posé des questions spécifiques sur Jersey, vous pouvez également lire l’article Implémentation des services RESTful avec JAX-RS et WebSphere 8.5 Liberty Profile dans lequel j’ai décrit le processus de publication no-web.xml pour WebSphere Liberty Profile (avec Apache Wink JAX-RS).
Vous devez configurer les bonnes dépendances dans pom.xml
javax.servlet javax.servlet-api 3.0.1 provided org.glassfish.jersey.containers jersey-container-servlet
Plus de détails ici: Exemple de démarrage pour jax-rs
Comme @ Eran-Medan l’a fait remarquer, JBoss EAP 7.1 (notez sans application Web, donc pas de servlet, je le faisais dans un projet EJB 3.2), je devais append l’atsortingbut “value” en tant que tel. L’atsortingbut value était requirejs.
Cela a fonctionné pour moi
@ApplicationPath(value="/*") public class MyApplication extends Application { private Set singletons = new HashSet(); public MyApplication() { singletons.add(new MyService()); } ... }
Trace de la stack
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
Les dépendances précédemment mentionnées n’ont pas fonctionné pour moi. Du Jersey Guide de l’utilisateur:
Jersey fournit deux modules Servlet. Le premier module est le module Servlet Core de Jersey qui fournit le support d’intégration principal de Servlet et est requirejs dans tout conteneur Servlet 2.5 ou supérieur:
org.glassfish.jersey.containers jersey-container-servlet-core
Pour prendre en charge des modes de déploiement Servlet 3.x supplémentaires et un modèle de programmation de ressources JAX-RS asynchrone, un module Jersey supplémentaire est requirejs:
org.glassfish.jersey.containers jersey-container-servlet
Le module jersey-container-servlet dépend du module jersey-container-servlet-core. Par conséquent, lorsqu’il est utilisé, il n’est pas nécessaire de déclarer explicitement la dépendance jersey-container-servlet-core.
https://jersey.github.io/documentation/latest/deployment.html#deployment.servlet.3