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:24] lmedini |
enseignement:tp:sw:jaxws:2016 [2016/12/09 15:42] (Version actuelle) ecoquery [Contrôleur principal (front)] |
====== 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_ [SpringBoot](https://projects.spring.io/spring-boot/) ainsi que le _framework_ [CXF](http://cxf.apache.org/). | 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_ImplWS` de 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 `metier` implé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 `services` contient 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` ([doc](http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html)) 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 ==== |
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 [`@WebService`](https://docs.oracle.com/javaee/7/api/index.html?javax/jws/WebService.html); | * annoté par ''[[https://docs.oracle.com/javaee/7/api/index.html?javax/jws/WebService.html|@WebService]]''; |
* utilise le composant `CoursManager` pour 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: [Bringing Spring Boot & Apache CXF up and running](https://blog.codecentric.de/en/2016/02/spring-boot-apache-cxf/), 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() { | // ne pas utiliser dispatcherServlet comme nom pour ce bean sous peine de |
return new ServletRegistrationBean(new CXFServlet(), "/soap-api/*"); | // ne plus pouvoir utiliser de bean @Controller ailleurs dans l'application |
} | @Bean |
| public ServletRegistrationBean cxfDispatcherServlet() { |
@Bean(name=Bus.DEFAULT_BUS_ID) | return new ServletRegistrationBean(new CXFServlet(), "/soap-api/*"); |
public SpringBus springBus() { | } |
return new SpringBus(); | |
} | @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). | </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). |
> 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) | |
| |
Aller à l'URL [`http://localhost:8080/soap-ui/`](http://localhost:8080/soap-ui/) et vérifiez que votre service est bien listé. | <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> |
| |
Tester son fonctionnement avec [soapUI](http://www.soapui.org/). | 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]]. |
| |
==== Contrôleur du service ==== | ==== Contrôleur 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. | 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 `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. | |
| Déployer ce composant comme un Web service à une autre adresse et tester avec [[http://www.soapui.org/|soapUI]]. |
| |
Déployer ce composant comme un Web service à une autre adresse et tester avec [soapUI](http://www.soapui.org/). | ==== Contrôleur principal (front) ==== |
| |
==== Contrôleur principal (_front_) ==== | 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. |
| |
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. | Utiliser [[http://www.soapui.org/|soapUI]] pour tester votre contrôleur point d'accès. |
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. | |
| |
Utiliser [soapUI](http://www.soapui.org/) pour tester votre contrôleur point d'accès. | <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> |
| <note important>Attention au nom de la dispatcherServlet dans la configuration Spring (maj du 09/12/2016)</note> |
| <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> |
| |
> 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. | 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> |
| |
| |
<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> | |