Java appelle WebService. Lorsque vous vous contactez pour la première fois, vous penserez que c'est un cauchemar, surtout sans implémentation standard unifiée. Par rapport à l'implémentation de service Web qui peut être achevé en quelques étapes de .NET, il est vraiment triste de voir la mise en œuvre de Java. Mais même si nous sommes tristes, nous devons toujours le terminer. Java a également de nombreuses bonnes implémentations, telles que Xfire, Jersey, CXF. Ici, nous allons jeter un œil à la mise en œuvre de XFire ensemble.
1) Tout d'abord, bien sûr, je dois descendre du sac, et cette personne ordinaire le sait. http://xfire.codehaus.org/download vous pouvez aller ici, vous pouvez aller tout ou distribution. Mais il vaut mieux lui donner beaucoup de problèmes étranges pour perdre confiance.
Que dois-je faire si je retire le sac? Mettez-le dans le projet. Cela semble absurde, mais beaucoup de gens ne savent tout simplement pas quoi faire.
Pour construire un nouveau projet, je le compare à XfireWebService, qui est bien sûr un projet Web ici.
J'ai mis tous ses packages ici. Après tout, lorsque nous écrivons des exemples, il n'est pas nécessaire d'être difficile. Cliquez sur le point avec désinvolture. Si vous souhaitez voir les informations d'exception, vous pouvez les ajouter lentement. Il est facile d'éliminer les erreurs à l'avenir, mais nous ne le ferons pas ici. Après tout, il n'y a rien de laid dans le manque d'exceptions, et vous pouvez les éliminer vous-même.
2) Comprenons d'abord la différence entre XFire et d'autres cadres WebService. La plus grande différence est qu'il nécessite une interface, et si vous devez utiliser XFire pour appeler le service Web correspondant, vous devez connaître la définition de l'interface. Je pense qu'il y a un peu de limitation ici. Mais à part cela, il est tout à fait pratique d'appeler WebService, tout comme appeler des méthodes locales. Jetons un coup d'œil directement à l'exemple:
Tout d'abord, l'interface la plus importante:
Interface publique iReaderService {lecteur public getReader (nom de chaîne, mot de passe de chaîne); Liste publique <Deader> getReaders (); } Il y a une interface, bien sûr, il doit y avoir une classe d'implémentation, sinon l'interface n'aura aucun sens. public class ReaderService implémente iReaderservice {lecteur public getReader (nom de chaîne, mot de passe de chaîne) {return new Reader (nom, mot de passe); } public list <Deader> getReaders () {list <nderser> ReaderList = new ArrayList <Dener> (); ReaderList.add (nouveau lecteur ("Shun1", "123")); ReaderList.add (nouveau lecteur ("Shun2", "123")); return ReaderList; }} Jetez également un œil aux cours de Javabean et Reader:
lecteur de classe publique {private statique final long SerialVersionUID = 1l; nom de chaîne privé; mot de passe de chaîne privé; Public Reader () {} Public Reader (String Name, String Motword) {this.name = name; this.password = mot de passe; } // get / set Method omet public String toString () {return "name:" + name + ", mot de passe:" + mot de passe; }}Notez que notre classe de lecture implémente ici l'interface sérialisable, pourquoi? Ici, tout d'abord, nous devons comprendre le principe du service Web. Pour Java, si nous avons besoin de télécharger des objets sur Internet, de nombreuses personnes penseront bien sûr à la sérialisation. Soit dit en passant, c'est la sérialisation, car nous devons passer le lecteur en tant que paramètre. Cela doit être mis en œuvre de force dans la version précédente, sinon une erreur sera signalée. Cependant, la dernière version (en fait, la dernière est également à partir de 2007, car XFire a cessé de se développer et a été fusionné dans un projet CXF par Apache. Nous en parlerons plus tard) n'est plus nécessaire. Quant à la façon de le mettre en œuvre, nous ne l'étudierons pas en profondeur ici pour le moment, car il a été fusionné en CXF. Si nous voulons apprendre en profondeur, il devrait être préférable d'apprendre le CXF.
3) Après avoir terminé l'interface ci-dessus et l'écriture de Javabean, beaucoup de gens demanderont, je vois que de nombreux services Web auront des fichiers WSDL, alors comment l'avez-vous obtenu? Avant d'en parler, discutons de ce qu'est WSDL. Peut-être que de nombreuses entreprises fournissent des interfaces qui ne sont que des adresses HTTP, le retour des formats XML, tout comme le nôtre. Cela a un avantage et un inconvénient. L'avantage est que notre développement est moins difficile, tandis que l'inconvénient est que nous devons fournir aux utilisateurs un tas de fichiers d'explication. Que signifie chaque balise XML retournée? Ce n'est rien, mais c'est juste ennuyeux. Quant à WebService, l'inconvénient est que nous avons développé un peu plus de choses, et l'avantage est que nous n'avons pas à écrire autant de fichiers d'explication, car il existe une explication unifiée appelée WSDL. Il s'agit du document d'explication de WebService, qui est unifié et le même quelle que soit la langue, il n'y a donc pas de problème que personne ne peut comprendre.
Et ici, lorsque nous déployons XFire, cela peut nous aider à générer des fichiers WSDL.
Le problème est de savoir comment le déployer, c'est en fait simple. Nous créons un nouveau dossier Meta-Inf dans le répertoire SRC, puis créons un dossier xfire, et créons le fichier Services.xml. La structure suivante est la suivante:
Certaines personnes peuvent demander pourquoi nous devons le construire dans le répertoire SRC. En fait, ce n'est pas une version prescrite ici, mais parce que nous devons demander les outils de développement pour nous aider à déployer ces fichiers nous-mêmes, donc si nous le mettons ici, Eclipse peut nous aider à le déployer sur Tomcat ou d'autres conteneurs nous-mêmes. Notez que le niveau de dossier où ce fichier est situé est fixé et ne peut pas être modifié.
Jetons un coup d'œil à Services.xml directement:
<? xml version = "1.0" Encoding = "utf-8"?> <Beans xmlns = "http://xfire.codehaus.org/config/1.0"> <fréditeur> <! - Le nom du WebServiceq, vous avez besoin de spécifier cela lorsque vous appelez -> <name> lecteur </nom> <! - Ce n'est généralement pas le site Web. -> <namespace> http: // test / helloService </ namespace> <! - Classe d'interface -> <ServiceClass> com.xfire.servlet.irederservice </ ServiceClass> <!
Il est généralement normal de regarder les commentaires.
4) Beaucoup de gens pensent que cela suffit. Non, cela n'a pas encore fonctionné. Si vous le spécifiez, comment les autres peuvent-ils le visiter? Comment transmettre la demande correspondante à xfire et le laisser le traiter. Nous devons à nouveau modifier le web.xml.
Après modification, ce qui suit est:
<? xml version = "1.0" Encoding = "utf-8"?> <web-app xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns = "http://java.sun.com/xml/ns/javaee" xmlns: web = "http://java.sun.com/xml/ns/javaee" xmlns: web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" XSI: ScheMalocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id = "webapp_id" version = "3.0"> <servlet> <Serplet-Name> xfireServert </ Servile-Med-Me <Serplet-Class> org.codehaus.xfire.transport.http.xfireConfigurableServlet </Servlet-Class> </Servlet> <Serplet-Mapping> <Serplet-Name> XFireServlet </vrlett-name> <url-Pattern> / Service / * </url-Pattern>
En fait, il suffit d'ajouter un servlet et la cartographie correspondante. Ensuite, nous entrons directement dans le navigateur:
http: // localhost: 8080 / xfirewebservice / services / ReaderService? WSDL
Nous pouvons voir:
Ce qui est affiché ici est WSDL, qui affichera la méthode que nous définissons et le type renvoyé. Il y a une explication de WSDL plus tard.
5) Après avoir terminé les quatre étapes ci-dessus, nous avons terminé le déploiement du service Web. D'autres peuvent appeler le service Web correspondant pour accéder à nos méthodes. Utilisons le client fourni par XFire pour accéder au service de site Web que nous venons de publier:
classe publique ReaderLIENT {public static void main (String [] args) {// voici pour créer un service, et une classe d'interface doit être transmise, car nous devons appeler le service d'interface correspondant SrcModel = new ObjectServiceFactory (). Create (irederservice.class); // Agent Factory, voici pour créer la classe d'interface correspondante plus tard xfireproxyfactory factory = new xfireproxyfactory (xfirefactory.newinstance (). GetXfire ()); // Adresse WebService, aucun wsdl ne doit être ajouté à la chaîne ReaderServiceUrl = "http: // localhost: 8080 / xfirewebservice / services / ReaderService"; essayez {// Utilisez l'usine pour renvoyer la classe d'interface correspondante ireaderservice ReaderService = (ireaderservice) factory.create (srcModel, ReaderServiceUrl); Reader Reader = ReaderService.getReader ("shun", "123"); System.out.println (lecteur); } catch (malformEdUrException e) {e.printStackTrace (); }}} De cette façon, nous voyons que la sortie est:
Analyse de la structure de fichiers WSDL
WSDL (Langue de description des services Web, Langue description du service Web) est une application XML qui définit une description du service Web comme un ensemble de points d'accès au service à travers lesquels les clients peuvent accéder aux services contenant des informations de document ou des appels de procédure (similaires aux appels de procédure distante). WSDL résume d'abord l'opération d'accès et le message de demande / réponse utilisé pendant l'accès, puis le lie à un protocole de transport spécifique et au format de message pour définir finalement le point d'accès spécifique du service déployé. Les points d'accès au service pour les déploiements spécifiques connexes deviennent des services Web abstraits via la combinaison. Cet article expliquera en détail la structure du document WSDL et analysera le rôle de chaque élément.
1: Définition WSDL
WSDL est un document utilisé pour décrire avec précision les services Web, et un document WSDL est un document XML qui suit le modèle XML WSDL. Le document WSDL définit un service Web comme une collection de points d'accès ou de ports. Dans WSDL, puisque la définition abstraite des points et des messages d'accès au service a été séparé du déploiement spécifique du service ou du format de données, la définition abstraite peut être utilisée à nouveau: le message se réfère à une description abstraite des données échangées; et le type de port fait référence à une collection abstraite d'opérations. Des protocoles spécifiques et des spécifications de format de données pour des types de ports spécifiques constituent une liaison qui peut être réutilisée. Associant une adresse d'accès Web à une liaison réutilisable, un port peut être défini et une collection de ports est définie comme un service.
Un document WSDL contient généralement 7 éléments importants, à savoir les types, l'importation, les messages, le porttype, le fonctionnement, la liaison et les éléments de service. Ces éléments sont imbriqués dans l'élément de définitions, qui est l'élément racine du document WSDL. La prochaine partie de l'article présentera en détail la structure de base de WSDL.
2: Structure de base de WSDL - Overview
Comme décrit à la fin de la première partie, un document WSDL de base contient 7 éléments importants. Les éléments suivants présenteront ces éléments et leurs fonctions.
Le document WSDL utilise les éléments suivants dans la définition d'un service Web:
・ Types - Un conteneur défini par un type de données, qui utilise un certain système de type (généralement le système de type dans le schéma XML).
・ Message - Type de résumé Définition des structures de données pour les messages de communication. Utilisez les types définis par les types pour définir la structure de données de l'ensemble du message.
・ Opération - Une description abstraite des opérations prises en charge dans le service. Généralement, une seule opération décrit une paire de messages de demande / réponse qui accède à l'entrée.
・ Portype - Une collection abstraite d'opérations prise en charge par un certain type de point d'entrée d'accès, qui peut être pris en charge par un ou plusieurs points d'accès au service.
・ LIAISSANCE - LIAISON DE PROTOCOLES SPÉCIFIQUES ET SPÉCIFICATIONS DE FORMAT DE DONNÉES pour des types de ports spécifiques.
・ PORT - Défini comme un point d'accès à service unique qui combine la liaison du protocole / format de données avec des adresses d'accès Web spécifiques.
・ Service - Une collection de points d'accès aux services connexes.
Le schéma XML de WSDL peut être appelé URL suivant: http://schemas.xmlsoap.org/wsdl/
Trois: Structure de base de WSDL - Description découragée
Cette section décrira en détail le rôle de chaque élément du document WSDL via un exemple. L'exemple suivant est le contenu d'un simple document WSDL. Pour la génération de ce document, veuillez vous référer à mon autre article: Exemple de développement XFire - Helloworld.
Un document WSDL de service Web simple qui prend en charge une opération unique appelée Sayhello, qui est implémentée en exécutant le protocole SOAP sur HTTP. La demande accepte un nom de chaîne et renvoie une chaîne simple après le traitement. La documentation est la suivante:
<? xml version = "1.0" Encoding = "utf-8"?> <wsdl: Définitions cibleNamespace = "http: //com.liuxiang.xfiredemo/helloservice" xmlns: tns = "http: //com.liuxiang.xfiredemo/helloservice" xmlns: wsdlsoap = "http://schemas.xmlsoap.org/wsdl/soap/" xmlns: soap12 = "http://www.w3.org/2003/05/soap-envelope" xmlns: xsd = "http://www.w3.org/2001/xmlschema" xmlns: soapenc11 = "http://schemas.xmlsoap.org/soap/encoding/" xmlns: soapenc12 = "http://www.w3.org/2003/05/soap-coding" xmlns: soap11 = "http://schemas.xmlsoap.org/soap/envelope/" xmlns: wsdl = "http://schemas.xmlsoap.org/wsdl/"> <wsdl: types> <xsd: schema xmlns: xsd = "http://www.w3.org/2001/xmlschema" attributDefault = "Qualified" élémentForlt = "Qualifet" AttributformDefaul TargetNamespace = "http: //com.liuxiang.xfiredemo/helloservice"> <xsd: élément name = "sayhello"> <xsd: complexType> <xsd: séquence> <xsd: élément maxoccurs = "1" minoccurs = "1" name = "name" nillable = "true" type = "xsd:" 1 "name =" name "nillable =" true "type =" xsd: "1" name = "name" nillable = "true" type = "xsd:" 1 "name =" name "nillable =" true "type =" </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="sayHelloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:string" /> </xsd:sequence> </ xsd: complexType> </xsd: élément> </ xsd: schéma> </ wsdl: types> <wsdl: message name = "sayhelloresponse"> <wsdl: part name = "paramètres" élément = "tns: Sayhelloloresnponse" /> </wsdl: message> <wsdl: message name = "sayhellore <wsdl: pièce nom = "paramètres" élément = "tns: sayhello" /> </ wsdl: message> <wsdl: portype name = "HelloserviceportType"> <wsdl: opération name = "sayhello"> <wsdl: entrée name = "sayhellorest" Message = "TNS: SayHellorest" name = "sayhelloresponse" message = "tns: sayhelloresponse" /> </ wsdl: operation> </ wsdl: porttype> <wsdl: liant name = "heloservicehttpbinding" type = "tns: helloserviceporttype"> <wsdlsoap: binding Style = "document" document " transport = "http://schemas.xmlsoap.org/soap/http" /> <wsdlsoap: opération name = "sayhello"> <wsdlsoap: opération soapaction = "" /> <wsdlsoap: opération soapaction = "" /> <wsdlsoap: body use = "littéral" /> <wsdl: entrée> <wsdlsoap: body use = "littéral" /> </ wsdl: output> </ wsdl: operation> </ wsdl: binding> <wsdl: service name = "heloservice"> <wsdl: port name = "HelloserviceHttppt" location = "http: // localhost: 8080 / xfire / services / helloService" /> </ wsdl: port> </ wsdl: service> </ wsdl: définitions>
L'élément Types utilise le langage du schéma XML pour déclarer des types de données et des éléments complexes utilisés ailleurs dans le document WSDL;
L'élément d'importation est similaire à l'élément d'importation dans un document de schéma XML et est utilisé pour importer des définitions WSDL à partir d'autres documents WSDL;
L'élément de message décrit la charge utile d'un message en utilisant le type intégré, le type complexe ou l'élément du schéma XML défini dans l'élément type du document WSDL ou défini dans le document WSDL externe référencé par l'élément d'importation;
L'élément Portype et l'élément d'opération décrivent l'interface du service Web et définissent ses méthodes. L'élément Portype et l'élément de fonctionnement sont similaires à la déclaration de méthode définie dans l'interface Java. L'élément de fonctionnement utilise un ou plusieurs types de messages pour définir la charge utile de ses entrées et de ses sorties;
L'élément de liaison attribue l'élément Portype et l'élément de fonctionnement à un protocole spécial et un style de codage;
L'élément de service est responsable de l'attribution de l'adresse Internet à une liaison spécifique;
1. Définitions Éléments
L'élément racine de tous les documents WSDL est un élément de définitions. Cet élément résume l'intégralité du document tout en fournissant un document WSDL via son nom. Cet élément n'a pas d'autre fonction, sauf fournir un espace de noms, il ne sera donc pas décrit en détail.
Le code suivant est la structure d'un élément de définitions:
<wsdl: Définitions TargetNamespace = "http: //com.liuxiang.xfiredemo/helloservice" xmlns: tns = "http: //com.liuxiang.xfiredemo/helloservice" xmlns: wsdlsoap = "http://schemas.xmlsoap.org/wsdl/soap/" xmlns: soap12 = "http://www.w3.org/2003/05/soap-envelope" xmlns: xsd = "http://www.w3.org/2001/xmlschema" xmlns: soapenc11 = "http://schemas.xmlsoap.org/soap/encoding/" xmlns: soapenc12 = "http://www.w3.org/2003/05/soap-coding" xmlns: soap11 = "http://schemas.xmlsoap.org/soap/envelope/" xmlns: wsdl = "http://schemas.xmlsoap.org/wsdl/"> </ wsdl: définitions>
2. Types des éléments
WSDL adopte les types intégrés du schéma XML W3C comme système de type de base. L'élément de types est utilisé comme un conteneur pour définir divers types de données non décrits dans les types intégrés du schéma XML. Lors de la déclaration de la charge utile de la partie du message, la définition du message utilise les types de données et les éléments définis dans l'élément de type. Définitions de types dans ce document WSDL:
<wsd: types> <xsd: schéma xmlns: xsd = "http://www.w3.org/2001/xmlschema" attributformDefault = "qualifié" elementFormDefault = "qualifié" TargetNamespace = "http: //com.liuxiang.xfiremo/HellOSVIC name = "sayhello"> <xsd: complexType> <xsd: séquence> <xsd: élément maxoccurs = "1" minoccurs = "1" name = "name" nillable = "true" type = "xsd: string" /> </ xsd: séquence> </ xsd: complexType> </xsd: élément> <xsd: complexType> <xsd: séquence> <xsd: élément maxoccurs = "1" minoccurs = "1" name = "out" nillable = "true" type = "xsd: string" /> </ xsd: séquence> </ xsd: complextype> </xsd: élément> </xsd: schema>
Ce qui précède est la partie de définition des données, qui définit deux éléments, l'un est Sayhello et l'autre est Sayhelloresponse:
Sayshello: définit un type complexe qui ne contient qu'une chaîne simple, qui est utilisée pour décrire la partie entrante de l'opération à l'avenir;
Sayshelloresponse: définit un type complexe qui ne contient qu'une chaîne simple et la valeur de retour utilisée pour décrire l'opération à l'avenir;
3. Éléments d'importation
L'élément d'importation permet d'utiliser les éléments de définition dans l'espace de noms spécifié dans d'autres documents WSDL dans le document WSDL actuel. L'élément d'importation n'est pas utilisé dans cet exemple. Cette fonction est généralement très efficace lorsque les utilisateurs souhaitent modulariser les documents WSDL.
Le format d'importation est le suivant:
<wsdl: importation namespace = "http://xxx.xxx.xxx/xxx/xxx" location = "http://xxx.xxx.xxx/xxx/xxx.wsdl" />
Il doit y avoir un attribut d'espace de noms et un attribut d'emplacement:
Attribut d'espace de noms: la valeur doit correspondre à TargetNamespace déclaré dans le document WSDL importé;
Attribut d'emplacement: doit pointer vers un document WSDL réel, et le document ne peut pas être vide.
4. Éléments de message
L'élément de message décrit la charge utile d'un service Web à l'aide de messages. L'élément de message peut décrire la charge utile de la sortie ou l'acceptation du message; Il peut également décrire le contenu de l'en-tête de fichier SOAP et l'élément de détail d'erreur. La façon dont l'élément de message est défini dépend de l'utilisation de la messagerie de style RPC ou de style de document. Dans la définition de l'élément de message dans cet article, ce document utilise la messagerie de style document:
<wsdl: message name = "sayhelloresponse"> <wsdl: pièce nom = "paramètres" élément = "tns: sayhelloresponse" /> </ wsdl: message> <wsdl: message name = "sayhellorequest"> <wsdl: part name = "paramètres" élément = "tns: disehello" /> </ wsdl: Message> element = "tns: Sayhello" /> </ wsdl: Message> Element = "tns"
Cette partie est une définition abstraite du format de message: deux messages Sayhelloresponse et Sayhellorequest sont définis:
SayshellOrequest: le format de message de demande de l'opération Sayhello, composé d'un fragment de message, des paramètres nommés, et l'élément est l'élément du type que nous avons défini précédemment;
Sayshelloresponse: le format de message de réponse de l'opération Sayhello est composé d'un fragment de message, des paramètres nommés, et l'élément est l'élément dans les types que nous avons définis précédemment;
Si vous utilisez la messagerie de style RPC, il vous suffit de modifier l'élément dans le document à taper.
5. Élément Portype
L'élément Portype définit l'interface abstraite du service Web. Cette interface est un peu similaire aux interfaces Java, qui définissent toutes deux un type et une méthode abstraits, et aucune implémentation n'est définie. Dans WSDL, l'élément Portype est implémenté par des éléments de liaison et de service, qui sont utilisés pour illustrer le protocole Internet, le schéma de codage et l'adresse Internet utilisée par l'implémentation du service Web.
Les opérations multiples peuvent être définies dans un porttype, et une opération peut être considérée comme une méthode. La définition du document WSDL dans cet article:
<wsdl: Portype name = "HelloserviceportType"> <wsdl: operation name = "sayhello"> <wsdl: entrée name = "sayhellorest" message = "tns: sayhellorequest" /> <wsdl: output name = "sayhelloresponse": "tns: Sayhelloresponse" </ wsdl: Portype>
Portype définit le type de mode d'appel du service. Il contient une méthode d'opération Sayshello, qui contient à la fois l'entrée et la sortie pour indiquer que l'opération est un mode de demande / réponse. Le message de la demande est le Sayhellorequest défini précédemment, et le message de réponse est le Sayhelloloresponse défini précédemment. L'entrée représente la charge utile fournie au service Web et le message de sortie représente la charge utile livrée au client.
6. Liaison
L'élément de liaison mappe un porttype abstrait à un ensemble de protocoles spécifiques (SOAO et HTTP), de styles de messagerie et de styles de codage. Les éléments de liaison généralement sont utilisés avec les éléments propriétaires du protocole. Exemples dans cet article:
<wsdl: liant name = "HelloserviceHttpBinding" type = "tns: helloServiceportType"> <wsdlsoap: binding style = "document" transport = "http://schemas.xmlsoap.org/soap/http" /> <wsdl: opération nom = "SayHello"> <wsdSoAP: soapaction = "" /> <wsdl: input name = "sayhellorequest"> <wsdlsoap: body use = "littéral" /> </ wsdl: input> <wsdl: output name = "sayhelloresponse"> <wsdlsoap: body use = "littéral" /> </ wsdl: output>