Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
enseignement:tp:sw:jaxws:2016 [2016/12/06 23:33]
lmedini
enseignement:tp:sw:jaxws:2016 [2016/12/09 15:42] (Version actuelle)
ecoquery [Contrôleur principal (front)]
Ligne 1: Ligne 1:
 ====== TP Implémentation de services sur Java/Spring/CXF ====== ====== TP Implémentation de services sur Java/Spring/CXF ======
  
-L'objectif de ce TP est de comprendre les principes d'implémentation de Web services illustrés à travers la plateforme Java en utilisant le _framework_ [[https://projects.spring.io/spring-boot/|SpringBoot]] ainsi que le _framework_ [[http://cxf.apache.org/|CXF]]. +L'objectif de ce TP est de comprendre les principes d'implémentation de Web services illustrés à travers la plateforme Java en utilisant le //framework// [[https://projects.spring.io/spring-boot/|SpringBoot]] ainsi que le //framework// [[http://cxf.apache.org/|CXF]]. 
-  + 
-Un projet de démarrage est fourni et comprend l'implémentation de base des fonctionnalités métier (module `metier`).  +Un projet de démarrage est fourni et comprend l'implémentation de base des fonctionnalités métier (module ''%%metier%%''). Il vous sera demandé de compléter ce projet en développant une application SpringBoot permettant d'exposer sous la forme d'un ensemble de services Web.
-Il vous sera demandé de compléter ce projet en développant une application SpringBoot permettant d'exposer sous la forme d'un ensemble de services Web.+
  
 +URL de pull du projet: https://forge.univ-lyon1.fr/hg/tiw1-2016-services-base
 ===== Modalités de rendu ===== ===== Modalités de rendu =====
  
-Ce TP est à rendre pour le **dimanche 18/12/2016** en inscrivant l'indentifiant  d'un projet forge dans la case tomuss `TP8_ImplWSde l'UE "TIW1 Intergiciels et Services". +Ce TP est à rendre pour le **dimanche 18/12/2016** en inscrivant l'indentifiant d'un projet forge dans la case tomuss ''%%TP8_ImplWS%%'' de l'UE "TIW1 Intergiciels et Services". **Cet identifiant devra être saisi par les deux membres du binôme le cas échéant.**
-**Cet identifiant devra être saisi par les deux membres du binôme le cas échéant.**+
  
-> On rappelle que l'indentifiant d'un projet forge étudiant: +<note>On rappelle que l'indentifiant d'un projet forge étudiant: 
-* Commence par `p` +  * Commence par ''%%p%%'' 
-* N'est pas une URL (ne contient pas `http`, ni `https`)+  * N'est pas une URL (ne contient pas ''%%http%%'', ni ''%%https%%'') 
 +</note>
  
 ===== Code métier fourni ===== ===== Code métier fourni =====
  
-Le module `metierimplémente une fonctionnalité simple de création et gestion de cours en ligne. +Le module ''%%metier%%'' implémente une fonctionnalité simple de création et gestion de cours en ligne. Il est possible de créer un cours avec des intervenants (//i.e.// des enseignants), d'y ajouter des participants (//i.e.// des élèves) et d'envoyer une facture aux différentes organisations ayant envoyé des personnes suivre ce cours (en pratique: afficher une ligne dans le log).
-Il est possible de créer un cours avec des intervenants (_i.e.des enseignants), d'y ajouter des participants (_i.e.des élèves) et d'envoyer une facture aux différentes organisations ayant envoyé des personnes suivre ce cours (en pratique: afficher une ligne dans le log).+
  
-Le module `servicescontient un embryon de projet SpringBoot et constituera la base du code à développer dans ce TP.+Le module ''%%services%%'' contient un embryon de projet SpringBoot et constituera la base du code à développer dans ce TP.
  
 ===== Services SOAP ===== ===== Services SOAP =====
  
-On implémentera le service décrit dans le fichier `cours.wsdl`. +On implémentera le service décrit dans le fichier ''%%cours.wsdl%%''. On commencera par générer du code Java correspondant à la description du service et on implémentera le coeur du service. On reconsitituera ensuite de manière simplifiée le travail effectué par le framework CXF pour exposer le service.
-On commencera par générer du code Java correspondant à la description du service et on implémentera le coeur du service.  +
-On reconsitituera ensuite de manière simplifiée le travail effectué par le framework CXF pour exposer le service.+
  
 ==== Génération de code ==== ==== Génération de code ====
  
-Utiliser le plugin `cxf-codegen-plugin([[http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html|doc]]) pour générer une interface Java représentant le service à implémenter.+Utiliser le plugin ''%%cxf-codegen-plugin%%'' ([[http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html|doc]]) pour générer une interface Java représentant le service à implémenter.
  
-> Le code généré ne devra pas être versionné et se trouvera (par défaut) dans l'arborescence du répertoire `target`. +<note tip>Le code généré ne devra pas être versionné et se trouvera (par défaut) dans l'arborescence du répertoire ''%%target%%''. Il est d'ailleurs conseillé de ne pas configurer de ''%%sourceRoot%%''
-Il est d'ailleurs conseillé de ne pas configurer de `sourceRoot`+</note> 
- +Parcourir le code généré et faire le lien avec le contenu du fichier ''%%cours.wsdl%%''.
-Parcourir le code généré et faire le lien avec le contenu du fichier `cours.wsdl`.+
  
 ==== Composant d'implémentation du service ==== ==== Composant d'implémentation du service ====
Ligne 41: Ligne 37:
 Créer un composant Spring: Créer un composant Spring:
  
-  * qui implémente l'interface générée ; +  * qui implémente l'interface générée; 
-  * annoté par `[[https://docs.oracle.com/javaee/7/api/index.html?javax/jws/WebService.html|@WebService]]`+  * annoté par ''[[https://docs.oracle.com/javaee/7/api/index.html?javax/jws/WebService.html|@WebService]]''
-  * qui utilise le composant `CoursManagerpour l'implémentation du métier.+  * utilise le composant ''%%CoursManager%%'' pour l'implémentation du métier.
  
-Déployer ce composant dans CXF. On pourra pour celui s'inspirer du tutoriel suivant: [[https://blog.codecentric.de/en/2016/02/spring-boot-apache-cxf/|Bringing Spring Boot & Apache CXF up and running]], en particulier en adaptant le code ci-dessous pour activer le framework CXF :+Déployer ce composant dans CXF. On pourra pour celui s'inspirer du tutoriel suivant: [[https://blog.codecentric.de/en/2016/02/spring-boot-apache-cxf/|Bringing Spring Boot & Apache CXF up and running]], en particulier en adaptant le code ci-dessous pour activer le framework CXF:
  
-    @SpringBootApplication +<code java> 
-    public class SimpleBootCxfApplication { +@SpringBootApplication 
-      +public class SimpleBootCxfApplication { 
-        public static void main(String[] args) { +  
-     SpringApplication.run(SimpleBootCxfApplication.class, args); +    public static void main(String[] args) { 
-        } +    SpringApplication.run(SimpleBootCxfApplication.class, args);
-      +
-        @Bean +
-        public ServletRegistrationBean dispatcherServlet() { +
-            return new ServletRegistrationBean(new CXFServlet(), "/soap-api/*"); +
-        } +
-      +
-        @Bean(name=Bus.DEFAULT_BUS_ID) +
-        public SpringBus springBus() {       +
-            return new SpringBus(); +
-        }+
     }     }
-     +  
-Lire la suite de ce tutoriel pour comprendre comment exposer le composant Spring comme service via CXF (_i.e.ajouter le bean das la configuration et le rendre disponible via un endpoint CXF). +    // ne pas utiliser dispatcherServlet comme nom pour ce bean sous peine de  
-      +    // ne plus pouvoir utiliser de bean @Controller ailleurs dans l'application 
-> Attention: bien remplir l'annotation `@WebServiceen spécifiant de préférence à cet endroit l'emplacement du wsdl, plutôt que dans la configuration du `EndpointImpl`CXF. Attention également aux packages de `javax.xml.ws.Endpointet de `org.apache.cxf.jaxws.EndpointImpl(non précisés dans le tutoriel)+    @Bean 
 +    public ServletRegistrationBean cxfDispatcherServlet() { 
 +        return new ServletRegistrationBean(new CXFServlet(), "/soap-api/*"); 
 +    } 
 +  
 +    @Bean(name=Bus.DEFAULT_BUS_ID) 
 +    public SpringBus springBus() {       
 +        return new SpringBus(); 
 +    } 
 +
 +</code> 
 +Lire la suite de ce tutoriel pour comprendre comment exposer le composant Spring comme service via CXF (//i.e.// ajouter le bean das la configuration et le rendre disponible via un endpoint CXF). 
 + 
 +<note tip>Attention: bien remplir l'annotation ''%%@WebService%%'' en spécifiant de préférence à cet endroit l'emplacement du wsdl, plutôt que dans la configuration du ''%%EndpointImpl%%''CXF. Attention également aux packages de ''%%javax.xml.ws.Endpoint%%'' et de ''%%org.apache.cxf.jaxws.EndpointImpl%%'' (non précisés dans le tutoriel) 
 +</note>
  
-Allez à l'URL [[http://localhost:8080/soap-ui/]] et vérifiez que votre service est bien listé.+Aller à l'URL [[http://localhost:8080/soap-api/]] et vérifiez que votre service est bien listé.
  
 Tester son fonctionnement avec [[http://www.soapui.org/|soapUI]]. Tester son fonctionnement avec [[http://www.soapui.org/|soapUI]].
Ligne 77: Ligne 77:
 Le rôle de ce contrôleur est double: extraire le contenu XML dans des instances de classes Java et aiguiller la suite du traitement vers la bonne méthode du composant d'implémentation du service. Le rôle de ce contrôleur est double: extraire le contenu XML dans des instances de classes Java et aiguiller la suite du traitement vers la bonne méthode du composant d'implémentation du service.
  
-Créer un nouveau composant Spring implémentant l'interface [`Provider<Source>`](https://docs.oracle.com/javaee/7/api/index.html?javax/xml/ws/Provider.html). +Créer un nouveau composant Spring implémentant l'interface ''[[https://docs.oracle.com/javaee/7/api/index.html?javax/xml/ws/Provider.html|Provider<Source>]]''. La méthode ''%%invoke%%'' devra convertir le XML du //payload// en objets Java et appeler la bonne méthode du composant d'implémentation du service que vous avez mis en place à l'étape précédente. 
-La méthode `invokedevra convertir le XML du _payload_ en objets Java et appeler la bonne méthode du composant d'implémentation du service que vous avez mis en place à l'étape précédente.+ 
 +Déployer ce composant comme un Web service à une autre adresse et tester avec [[http://www.soapui.org/|soapUI]]. 
 + 
 +==== Contrôleur principal (front) ====
  
-Déployer ce composant comme un Web service à une autre adresse et tester avec [soapUI](http://www.soapui.org/).+Implémenter un contrôleur point d'accès au service via un ''[[http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/web/servlet/mvc/Controller.html|@Controller]]'' SpringMVC. Ce contrôleur traitera les requêtes HTTP et extraira le contenu (//payload//) du message via l'API SAAJ. Il redirigera ensuite le traitement vers le composant Web service provider de l'étape précédente.
  
-==== Contrôleur principal (_front_) ====+Utiliser [[http://www.soapui.org/|soapUI]] pour tester votre contrôleur point d'accès.
  
-Implémenter un contrôleur point d'accès au service via un [`@Controller`](http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/web/servlet/mvc/Controller.html) SpringMVC.  +<note>Comme indiqué dans ''%%cours.wsdl%%'', le service déployé devra être accessible à l'adresse [[http://localhost:8080/services-sans-cxf/cours]]Il faut donc bien configurer le ''%%@RequestMapping%%'' en fonction de cette URL.</note> 
-Ce contrôleur traitera les requêtes HTTP et extraira le contenu (_payload_) du message via l'API SAAJ+<note important>Attention au nom de la dispatcherServlet dans la configuration Spring (maj du 09/12/2016)</note> 
-Il redirigera ensuite le traitement vers le composant Web service provider de l'étape précédente.+<note tip>Pour fabriquer correctement les ''MimeHeaders'', il faut les copier via une boucle depuis les headers de la requête HTTP.</note> 
 +<note tip>En cas d'utilisation de l'API XML de transformation pour faire des copies entre représentations XML, penser à ''SAAJResult'' qu ipermet d'écrire dans noeud XML d'un message SOAP</note>
  
-Utiliser [soapUI](http://www.soapui.org/) pour tester votre contrôleur point d'accès.+Auteur: <html><a href="http://liris.cnrs.fr/ecoquery/"></html>Emmanuel Coquery<html></a><br/></html> <html><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="license"><img src="https://licensebuttons.net/l/by-nc-sa/3.0/80x15.png" alt="CC Attribution-Noncommercial-Share Alike 3.0 Unported" /></a></html> Ce document est placé sous les termes de la licence suivante : <html><bdi><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="license" class="urlextern"></html>CC Attribution-Noncommercial-Share Alike 3.0 Unported<html></a></bdi></html>
  
-> Comme indiqué dans `cours.wsdl`, le service déployé devra être accessible à l'adresse [`http://localhost:8080/services-sans-cxf/cours`](http://localhost:8080/services-sans-cxf/cours). Il faut donc bien configurer le `@RequestMapping` en fonction de cette URL. 
  
-<html> 
-<div class="license">Auteur: <a href="http://liris.cnrs.fr/ecoquery/">Emmanuel Coquery</a><br/> <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="license"><img src="https://licensebuttons.net/l/by-nc-sa/3.0/80x15.png" alt="CC Attribution-Noncommercial-Share Alike 3.0 Unported" /></a> Ce document est placé sous les termes de la licence suivante : <bdi><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="license" class="urlextern">CC Attribution-Noncommercial-Share Alike 3.0 Unported</a></bdi></div> 
-</html>