This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
wiki:epims4_0m2:developer:cxf_web-services [2008/03/26 10:07] barthe |
wiki:epims4_0m2:developer:cxf_web-services [2008/10/02 10:21] (current) |
||
---|---|---|---|
Line 6: | Line 6: | ||
==== Utilisation ==== | ==== Utilisation ==== | ||
- | Il faut tout d'abord importer les librairies nécessaires au fonctionnement de CXF. Pour l'utilisation faîtes dans ePims il est nécessaire de prendre les dépendances suivantes (facilement retrouvable grâce à la target //resolve// des build.xml). | + | Il faut tout d'abord importer les librairies nécessaires au fonctionnement de CXF. Pour l'utilisation faîtes dans ePims il est nécessaire de prendre les dépendances suivantes (facilement retrouvable grâce à la target ''resolve'' des build.xml). |
<code> | <code> | ||
commons-logging-1.1.jar | commons-logging-1.1.jar | ||
Line 36: | Line 36: | ||
== Configuration == | == Configuration == | ||
- | Côté serveur il faut tout d'abord écrire l'interface comportant les méthodes des services voulus ainsi que la classe d'implémentation de cette interface (nous prendrons respectivement pour exemple l'interface //IPlateServices// et son implémentation //PlateServices//). L'interface va servir à exposer en web-services uniquement les méthodes voulues et non pas toutes les méthodes présentes dans l'implémentation. | + | Côté serveur il faut tout d'abord écrire l'interface comportant les méthodes des services voulus ainsi que la classe d'implémentation de cette interface (nous prendrons respectivement pour exemple l'interface ''IPlateServices'' et son implémentation ''PlateServices''). L'interface va servir à exposer en web-services uniquement les méthodes voulues et non pas toutes les méthodes présentes dans l'implémentation. |
Afin d'exposer ces méthodes en web-services il faut configurer CXF et créer ou modifier 3 fichiers. | Afin d'exposer ces méthodes en web-services il faut configurer CXF et créer ou modifier 3 fichiers. | ||
- | * **springWSAppContext.xml** (si il n'existe pas ce fichier peut porter un autre nom) : ce fichier permet de déclarer dans Spring le bean de l'implémentation du web-services (//PlateServices//) et de définir ses propriétés (//delegate// est un attribut de la classe). **A noter** : l'identifiant de ce bean, qui sera utilisé ensuite. | + | * **springWSAppContext.xml** (si il n'existe pas ce fichier peut porter un autre nom) : ce fichier permet de déclarer dans Spring le bean de l'implémentation du web-services (''PlateServices'') et de définir ses propriétés (''delegate'' est un attribut de la classe). **A noter** : l'identifiant de ce bean, qui sera utilisé ensuite. |
<code xml> | <code xml> | ||
<bean id="plateServices" class="cea.edyp.platews.services.PlateServices"> | <bean id="plateServices" class="cea.edyp.platews.services.PlateServices"> | ||
Line 49: | Line 49: | ||
</code> | </code> | ||
- | * **services.xml** : déclaration des services. Pour chaque service à déclarer il faut faire une balise //simple:server//. Les "champs" à compléter sont : | + | * **services.xml** : déclaration des services. Pour chaque service à déclarer il faut faire une balise ''simple:server''. Les "champs" à compléter sont : |
* id : le nom du serveur du service | * id : le nom du serveur du service | ||
* serviceClass : l'interface du service (ici //IPlateServices//) | * serviceClass : l'interface du service (ici //IPlateServices//) | ||
Line 60: | Line 60: | ||
xmlns:soap="http://cxf.apache.org/bindings/soap" | xmlns:soap="http://cxf.apache.org/bindings/soap" | ||
xsi:schemaLocation=" | xsi:schemaLocation=" | ||
- | http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd | + | http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd |
- | http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd | + | http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd |
- | http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd"> | + | http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd"> |
Line 80: | Line 80: | ||
</simple:server> | </simple:server> | ||
</code> | </code> | ||
- | Nota: le //simple:dataBinding// permet de forcer CXF à utiliser Aegis comme transformateur Java -> XML. Par défaut il utilise JAXB, mais celui-ci s'est révélé, au moment de l'intégration de CXF au projet, source de bug. | + | Nota: le ''simple:dataBinding'' permet de forcer CXF à utiliser Aegis comme transformateur Java -> XML. Par défaut il utilise JAXB, mais celui-ci s'est révélé, au moment de l'intégration de CXF au projet, source de bug. |
Line 120: | Line 120: | ||
== Test == | == Test == | ||
- | En dehors des tests unitaires on peut tester le fonctionnement des web-services en les interrogeant avec des logiciels dédiés. Exemple : [[http://www.soapui.org/|SoapUI]]. Afin que le logiciel puisse construire des requêtes pour les services il faut lui donner le WSDL (le fichier de description du service). Celui-ci peut être atteint en ajoutant //?WSDL// à l'adresse du web-services. Pour notre exemple précédant l'url du WSDL sera donc <nowiki>http://edyp-epims:8008/eP-WS/PlateServices?WSDL</nowiki>. | + | En dehors des tests unitaires on peut tester le fonctionnement des web-services en les interrogeant avec des logiciels dédiés. Exemple : [[http://www.soapui.org/|SoapUI]]. Afin que le logiciel puisse construire des requêtes pour les services il faut lui donner le WSDL (le fichier de description du service). Celui-ci peut être atteint en ajoutant ''?WSDL'' à l'adresse du web-services. Pour notre exemple précédant l'url du WSDL sera donc <nowiki>http://edyp-epims:8008/eP-WS/PlateServices?WSDL</nowiki>. |
---- | ---- | ||
==== Client Web-services ==== | ==== Client Web-services ==== | ||
- | FIXME | + | === Création et utilisation === |
+ | La méthode de création de client utilisée dans ePims se base sur l'utilisation des interfaces des web-services. L'exemple pour cette partie sera pris sur la classe ''WSDataProvider'' qui permet d'interroger les services fournis par ''PlateServices''. | ||
+ | |||
+ | * Déclaration du client : il faut que CXF ait connaissance des signatures des méthodes des services qu'il interrogera. Il faut donc, à notre classe d'accès aux web-services (''WSDataProvider''), un attribut client du type de l'interface du services (accessible dans eP-Plate grâce à la librairie de communication eP-CoL). | ||
+ | <code java> | ||
+ | private IPlateServices client; | ||
+ | </code> | ||
+ | |||
+ | * Initialisation du client (dans le constructeur de la classe par exemple). Le client va être créé par une fabrique de CXF (''ClientProxyFactoryBean''). Il faut lui donner la classe du service (''IPlateServices''), l'url à interroger (exemple <nowiki>http://edyp-epims:8008/eP-WS/PlateServices</nowiki>) et, accessoirement, le //databinding// à utiliser (pour des raisons de compatibilité avec le serveur nous utilisons aussi Aegis pour le client). Puis il suffit de demander à la fabrique de créer le client et de l'affecter à notre attribut précédemment déclaré. | ||
+ | <code java> | ||
+ | ClientProxyFactoryBean factory = new ClientProxyFactoryBean(); | ||
+ | factory.setServiceClass(IPlateServices.class); | ||
+ | factory.setAddress(url.toString()); | ||
+ | factory.getServiceFactory().setDataBinding(new AegisDatabinding()); | ||
+ | client = (IPlateServices) factory.create(); | ||
+ | </code> | ||
+ | |||
+ | * Utilisation du client : il suffit d'appeler la méthode voulu du client. Par exemple si l'on veut récupérer une plaque virtuelle sachant son nom : | ||
+ | <code java> | ||
+ | IComVirtualPlate results = client.getVirtualPlate(name); | ||
+ | </code> | ||
+ | CXF lancera automatiquement une requête SOAP correctement formé à l'url donnée à la fabrique, attendra la réponse, la traitera et la fournira comme renvoie de la méthode appelée. :!: **Attention** : les objets renvoyés par CXF sont du bon type mais sont des proxy : ils n'ont que les méthodes d'accès get/set aux attributs, il faut donc faire une transposition de ces objets en //vrai// objets voulu. | ||
+ | |||
+ | |||
+ | ---- | ||
+ | ==== Nota Bene - Bugs - Problèmes rencontrés ==== | ||
+ | * Nous avons essayez d'utiliser des ''endpoint'' au tout début des l'implémentation, en lieu et place des ''server'' (cf le web.xml plus haut) mais ceux-ci générais une erreur au déploiement de l'application : | ||
+ | * <code> | ||
+ | Error creating bean with name 'plateServicesEndPoint': Invocation of init method failed; | ||
+ | nested exception is java.security.AccessControlException: access denied (javax.xml.ws.WebServicePermission publishEndpoint ) | ||
+ | </code> | ||
+ | * Apparemment il s'agirait d'un problème du ''SecurityManager'' de Tomcat auquel doit faire appel CXF (spec JEE5) pour autoriser la publication (''PUBLISH_PERMISSION'') des ''endpoint''. | ||
+ | * La solution appliquée à été d'utiliser à la place des balises ''endpoint'' des ''server'' qui eux n'ont pas besoin de PUBLISH_PERMISSION. | ||
+ | * Un autre solution aurait été de pouvoir configurer le serveur d'application pour qu'il accepte la publication des ''endpoint'', mais nous n'avons pas réussi à le faire. | ||