34
XML, SOAP, Services Web et JAVA Me SOAP Web Services on Smart Clients

XML, SOAP, Services Web et JAVA Me

  • Upload
    kapila

  • View
    47

  • Download
    3

Embed Size (px)

DESCRIPTION

XML, SOAP, Services Web et JAVA Me. SOAP Web Services on Smart Clients. Plan. Services Web XML over http SOAP - RPC. Avantages de SOAP. Support pour le typage Plus de 40 types de données avec les schémas XML Permet aux usagers de se définir des types de données complexes - PowerPoint PPT Presentation

Citation preview

Page 1: XML, SOAP, Services Web et JAVA Me

XML, SOAP, Services Web et JAVA Me

SOAP Web Services on Smart Clients

Page 2: XML, SOAP, Services Web et JAVA Me

Plan

Services Web XML over http SOAP - RPC

Page 3: XML, SOAP, Services Web et JAVA Me

Avantages de SOAP

Support pour le typage Plus de 40 types de données avec les schémas XML Permet aux usagers de se définir des types de données complexes

Messagerie flexible et répandue Supporte plusieurs schémas de messagerie dont

RPC synchrone, messages asynchrones, multicast (souscription), routage complexe des messages avec plusieurs intermédiaires

Standardisation Adhérence répandue à SOAP par les services web Profiter des standards XML qui peuvent être intégrés à SOAP ou utiliser SOAP

WSDL (Web Services Description Language), UDDI (Universal Description, Discovery, and Integration), et la plupart des registres XML;

XML Digital Signature, XML Encryption, SAML (Security Assertion Markup Language)

Rem: sérialisation d’objets Java En vecteur d’octets en tant qu’élément Base64 pour les transporter par SOAP Par contre, si on sait que tout se passe en Java, il vaut mieux utiliser RMI ou JMS

Page 4: XML, SOAP, Services Web et JAVA Me

Architecture des services web SOAP J2ME Web Services API (WSA)

Pour tout profil J2ME CDC ou CLDC remote invocation API

Sous-ensemble strict de J2SE Java API for XML-Based RPC (JAX-RPC 1.1),

+ quelques classes Remote Method Invocation (RMI) classes ajoutées pour satisfaire les dépendances de JAX-RPC

Un sous-ensemble strict de SAX, version 2

Page 5: XML, SOAP, Services Web et JAVA Me

Organisation d’une application fondée sur JSR

Page 6: XML, SOAP, Services Web et JAVA Me

JSR172 run-time et stubs

runtime Permet aux stubs de réaliser toutes les tâches associées à

l’invocation d’un RPC à service web Déterminer les propriétés spécifiques à une invocation RPC Décrire les valeurs d’entrée et le résultat d’une invocation RPC Encoder les valeurs d’entrée Invoquer le RPC au point de livraison du service web Décoder et rendre à l’application tout résultat rendu par le

service

Page 7: XML, SOAP, Services Web et JAVA Me

kSOAP

Construit au-dessus de l’analyseur kXML

http://ksoap2.sourceforge.net/ Empreinte petite : 41 K pour v2.1.2 Ne supporte pas la spécification entière de

SOAP

L’exemple qui suit est réalisé avec kSOAP v1.2

Page 8: XML, SOAP, Services Web et JAVA Me

Analyseur SOAP

Extraire directement les objets Java d’un document SOAP

Type-mapping Mashalling via un encodage sous forme de chaîne de

caractères

Comprends les informations de typage dans un document SOAP

Convertit automatiquement les éléments SOAP en objets Java

Serialisation / désérialisation devient transparente

Page 9: XML, SOAP, Services Web et JAVA Me

Exemple simple

Préparer les arguments à transmettre à la méthode distante Instancier un objet SOAP (SoapObject) Ajouter les arguments de l’appel addProperty()

Préparer le transport objet HttpTransport + URL destination

Invoquer la méthode distante Invocation de la méthode call() sur l’objet HttpTransport Le résultat est rendu par cette invocation

Page 10: XML, SOAP, Services Web et JAVA Me

private String licenseKey = "fVqHySRrXuf";private String endPointURL ="http://api.google.com/search/beta2";

/** * Simple spell check using convenience class HttpTransport * This function returns the Google suggested spell.* @param query the string to be spell corrected. */ public String spellCheck (String query) throws Exception { // Prepare request SOAP message in a memory object SoapObject method = new SoapObject("urn:GoogleSearch", "doSpellingSuggestion"); method.addProperty("key", licenseKey); method.addProperty("phrase", query);

// Prepare SOAP RPC call object. HttpTransport rpc = new HttpTransport(endPointURL); // Google uses 1999 SOAP standards. ClassMap cm = new ClassMap(Soap.VER10); rpc.setClassMap (cm);

// Conduct RPC call through HTTP and directly get results String spellSugg = (String) rpc.call (method);

System.out.println(rpc.requestDump); System.out.println(rpc.responseDump);

return spellSugg; }

Page 11: XML, SOAP, Services Web et JAVA Me

Fonctionnement de la méthode ‘call’

1- Sérialisation de l’objet SoapObject sous forme de message de requête avec les bons espaces de noms

<?xml version='1.0' encoding='UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">

<SOAP-ENV:Body> <ns1:doSpellingSuggestion xmlns:ns1="urn:GoogleSearch" SOAP-ENV:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/">

<key xsi:type="xsd:string">QLgFCbGCQD6710PlS</key><phrase xsi:type="xsd:string">phon</phrase>

</ns1:doSpellingSuggestion>

</SOAP-ENV:Body> </SOAP-ENV:Envelope>

Page 12: XML, SOAP, Services Web et JAVA Me

Fonctionnement de la méthode ‘call’

2. soumission de la requête au point de livraison à travers HTTP

3. récupération du message de réponse SOAP

<?xml version='1.0' encoding='UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:doSpellingSuggestionResponse xmlns:ns1="urn:GoogleSearch" SOAP-ENV:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/">

<return xsi:type="xsd:string">phone</return>

</ns1:doSpellingSuggestionResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

4. transformer la réponse en objet Java et rendre cet objet La chaîne « phone » de type String

Page 13: XML, SOAP, Services Web et JAVA Me

Transport des message en kSOAP

package org.ksoap.transport;

import java.io.*;import javax.microedition.io.*;

import org.kxml.*;import org.kxml.io.*;import org.kxml.parser.*;

import org.ksoap.*;

public class HttpTransport {

String url; String soapAction = "\"\"";

SoapEnvelope requestEnvelope = new SoapEnvelope (); SoapEnvelope responseEnvelope = new SoapEnvelope ();

HttpConnection connection; OutputStream os; InputStream is; InputStreamReader reader;

Page 14: XML, SOAP, Services Web et JAVA Me

Transport des message en kSOAP

/** Sends the requestEnvelope and fills the responseEnvelope @exception InterruptedIOException if transport was closed async.

@exception IOException if an error occurs*/public void call () throws IOException {

ByteArrayOutputStream bos = new ByteArrayOutputStream ();XmlWriter xw = new XmlWriter (new OutputStreamWriter (bos));requestEnvelope.write (xw);xw.flush ();bos.write ('\r');bos.write ('\n');byte [] requestData = bos.toByteArray ();bos = null;xw = null;

requestDump = debug ? new String (requestData) : null;responseDump = null;

Page 15: XML, SOAP, Services Web et JAVA Me

try { connected = true; connection = (HttpConnection) Connector.open (url, Connector.READ_WRITE, true);

connection.setRequestProperty ("SOAPAction", soapAction); connection.setRequestProperty ("Content-Type", "text/xml"); connection.setRequestProperty ("Content-Length", ""+requestData.length);

connection.setRequestProperty ("User-Agent", "kSOAP/1.0");

connection.setRequestMethod (HttpConnection.POST);

os = connection.openOutputStream (); os.write (requestData, 0, requestData.length); os.close ();

requestData = null;

is = connection.openInputStream ();

reader = new InputStreamReader (is); XmlParser xp = new XmlParser (reader);

responseEnvelope.parse (xp);

} finally { if (!connected) throw new InterruptedIOException (); reset (); } }

Page 16: XML, SOAP, Services Web et JAVA Me

Génération des stubs

IBM WebSphere Studio Device Developer

SunOne Studio

CodeWarrior Wireless Studio

Page 17: XML, SOAP, Services Web et JAVA Me

Fonctionnement interne de kSOAP v 1.2

Lorsque l’analyseur kSOAP rencontre un élément SOAP, l’analyseur lit l’élément XML dans un objet Java selon les règles suivantes:

Si l’élément SOAP est un des type primitifs prédéfini du tableau, il est converti dans un objet Java du type correspondant

Si l’élément SOAP n’a pas de fils, mais n’est pas un des types prédéfini, il est converti en un objet SoapPrimitive

On peut récupérer les informations de typage de l’élément originel SOAP via les méthodes SoapPrimitive.getNameSpace() et SoapPrimitive.getName()

On peut accéder la valeur de la chaîne de caractères via la méthode SoapPrimitive.toString()

Si l’élément SOAP a des fils, i.e. c’est un élément complexe, il est converti en objet implémentant l’interface KvmSerializable

La classe utilitaire SoapObject implémente cet interface On peut récupérer les information s typages via les méthodes

SoapObject.getNameSpace() et SoapObject.getName()

Les fils d’un élément complexe sont convertis en propriétés de leur parent SoapObject selon les règles précédentes.

Chaque propriété possède se voit aussi associé un objet PropertyInfo qui contient les informations comme le nom de l’élément SOAP et son type Java

Page 18: XML, SOAP, Services Web et JAVA Me

Structure des SoapObject

Parce qu’un objet SoapObject peut avoir des propriétés SoapObject, on peut l’utiliséer pour représenter des structures hiérarchiques complexes

Page 19: XML, SOAP, Services Web et JAVA Me

Sérialiser un objet

Pour sérialiser un objet Construire une représentaiton hiérarchique où

Toutes les feuilles doivent être soit un objet SoapPrimitive, soit un des quatre types prédéfinis

La racine par contre ne possède pas de paires (SoapObject, PropertyInfo), on a donc perdu en principe le nom de la racine lors de l’analyse

Utiliser un objet « writer » kSOAP pour sérialiser l’objet en mémoire dans un flot XML

Page 20: XML, SOAP, Services Web et JAVA Me

// SoapObject "method" is the calling construct // // the "" and "StockOrderParameters" here are// element name/namespace rather than SOAP type name/namespace

SoapObject method = new SoapObject("", "StockOrderParameters");method.addProperty("Symbol", "XYZ"); method.addProperty("From", "Michael Yuan"); method.addProperty("Shares", new Integer (1000)); method.addProperty("Buy", new Boolean (true)); method.addProperty("LimitPrice", new SoapPrimitive

("http://www.w3.org/2001/XMLSchema", "float", "123.4"));

// Assemble "method" into an enveloped SOAP message // and then export to a String

ByteArrayOutputStream bos = new ByteArrayOutputStream (); XmlWriter xw = new XmlWriter (new OutputStreamWriter (bos));

// Use default mapping between Java objects and Soap elements

SoapEnvelope envelope = new SoapEnvelope (new ClassMap (Soap.VER12)); envelope.setBody (method); envelope.write (xw); xw.flush (); bos.write ('\r'); bos.write ('\n'); byte [] requestData = bos.toByteArray ();String requestSOAPmesg = new String (requestData);

Page 21: XML, SOAP, Services Web et JAVA Me

Requête<SOAP-ENV:Envelope

xmlns:SOAP-ENC="http://www.w3.org/2001/12/soap-encoding" xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body

SOAP-ENV:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<StockOrderParameters id="o0" SOAP-ENC:root="1"> <Symbol xsi:type="xsd:string">XYZ</Symbol>

<From xsi:type="xsd:string">Michael Yuan</From> <Shares xsi:type="xsd:int">1000</Shares> <Buy xsi:type="xsd:boolean">true</Buy> <LimitPrice

xsi:type="xsd:float">123.45</LimitPrice> </StockOrderParameters> </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

Page 22: XML, SOAP, Services Web et JAVA Me

Réponse

Page 23: XML, SOAP, Services Web et JAVA Me

Récupérer les éléments de la réponse

ByteArrayInputStream bis = new ByteArrayInputStream (soapRespMesg.getBytes ()); InputStreamReader reader = new InputStreamReader (bis); XmlParser xp = new XmlParser (reader);

// Use default mapping between Java objects and Soap elements. SoapEnvelope envelope = new SoapEnvelope (new ClassMap (Soap.VER12)); envelope.parse (xp);

// Get the parsed structure. SoapObject orderStatus = (SoapObject) envelope.getResult();

// Retrieve the values as appropriate Java objects. String customerName = (String) orderStatus.getProperty ("CustomerName"); String symbol = (String) orderStatus.getProperty ("Symbol"); Integer share = (Integer) orderStatus.getProperty ("Share"); Boolean buy = (Boolean) orderStatus.getProperty ("Buy");

// Since the default mapping table has no "Float" type, there is no corresponding // Java object type for "xsd:float". So, as any unknown type, // this element is mapped to a "SoapPrimitive". SoapPrimitive price = (SoapPrimitive) orderStatus.getProperty ("Price"); SoapPrimitive execTime = (SoapPrimitive) orderStatus.getProperty ("ExecTime");

Page 24: XML, SOAP, Services Web et JAVA Me

Automatiser la sérialisation / désérialisation

Indiquer à l’analyseur la relation entre les type SOAP et les types Java Compléter la table de base

Indiquer à l’analyseur comment convertir les chaînes de caractères en objet Java Enregistrer dans la table un objet Marshal qui sait faire la

conversion

public interface Marshal { public Object readInstance ( SoapParser parser,

String namespace, String name, ElementType expected)

throws IOException;

public void writeInstance (SoapWriter writer, Object instance) throws IOException;

public void register (ClassMap cm); }

Page 25: XML, SOAP, Services Web et JAVA Me

La classe utilitaire org.ksoap.marshal.MarshalDate Public class MarshalDate implements Marshal

public Object readInstance ( SoapParser parser, String namespace, String name, ElementType expected)

throws IOException { parser.parser.read (); // Start tag Object result = IsoDate.stringToDate (

parser.parser.readText (), IsoDate.DATE_TIME);

parser.parser.read (); // End tag return result;

}

public void register (ClassMap cm) { cm.addMapping (cm.xsd, "dateTime", MarshalDate.DATE_CLASS, this);

}

Page 26: XML, SOAP, Services Web et JAVA Me

ClassMap.addMapping

/** Defines a direct mapping from a namespace and name to a Java class (and vice versa), using the given marshal mechanism */

public void addMapping (String namespace, String name, Class clazz, Marshal marshal)

{ qNameToClass.put ( new SoapPrimitive (namespace, name, null),

marshal == null ? (Object) clazz : marshal); classToQName.put ( clazz.getName (),

new Object [] {namespace, name, null, marshal});

if (prefixMap.getPrefix (namespace) == null) prefixMap = new PrefixMap (prefixMap, "n"+(cnt++), namespace);

}

Page 27: XML, SOAP, Services Web et JAVA Me

Ajout à la table des mappings avant de désérialiser la réponse

ByteArrayInputStream bis = new ByteArrayInputStream (mesg.getBytes ());

InputStreamReader reader = new InputStreamReader (bis); XmlParser xp = new XmlParser (reader);

// Register Marshal for "xsd:dateTime" type ClassMap cm = new ClassMap (Soap.VER12); Marshal md = new MarshalDate (); md.register (cm);

SoapEnvelope envelope = new SoapEnvelope (cm); envelope.parse (xp);

SoapObject orderStatus =(SoapObject)envelope.getResult(); Date execTime = (Date) orderStatus.getProperty ("ExecTime");

Page 28: XML, SOAP, Services Web et JAVA Me

La sérialisation des « array »

Page 29: XML, SOAP, Services Web et JAVA Me

La désérialisation sous forme de Vector

// Register Marshal for "xsd:dateTime" type ClassMap cm = new ClassMap (Soap.VER12); Marshal md = new MarshalDate (); md.register (cm);

SoapEnvelope envelope = new SoapEnvelope (cm); envelope.parse (xp);

SoapObject orderStatus = (SoapObject) envelope.getResult(); String customerName = (String) orderStatus.getProperty ("CustomerName"); Vector transactions = (Vector) orderStatus.getProperty ("Transactions");

// First element in the array SoapObject transaction0 = (SoapObject) transactions.elementAt(0); String symbol0 = (String) transaction0.getProperty ("Symbol"); Integer share0 = (Integer) transaction0.getProperty ("Share"); Boolean buy0 = (Boolean) transaction0.getProperty ("Buy"); SoapPrimitive price0 = (SoapPrimitive) transaction0.getProperty ("Price");

// Second element in the array SoapObject transaction1 = (SoapObject) transactions.elementAt(1);

String symbol1 = (String) transaction1.getProperty ("Symbol"); Integer share1 = (Integer) transaction1.getProperty ("Share"); Boolean buy1 = (Boolean) transaction1.getProperty ("Buy"); SoapPrimitive price1 = (SoapPrimitive) transaction1.getProperty ("Price");

Page 30: XML, SOAP, Services Web et JAVA Me

Validation des documents à l’aide des templates SOAP

Via la classe ClassMap Ajouter un objet template SoapObject à l’analyseur

Template un SoapObject vide avec de l’information sur

le type SOAP parent Les noms des éléments des enfants (properties) Leur type Java

Un fils peut lui-même être un template ce qui permet de construire des templates arbitrairement complexes

Si l’analyseur détecte une erreur, alors il lance une exception et s’arrête

Page 31: XML, SOAP, Services Web et JAVA Me

Une transaction doit contenir xsd:string value Symbol, xsd:int value Share, xsd:boolean value Buy,

xsd:float value Price

ByteArrayInputStream bis = new ByteArrayInputStream (arraySoapRespMesg.getBytes ());

InputStreamReader reader = new InputStreamReader (bis); XmlParser xp = new XmlParser (reader);

ClassMap cm = new ClassMap (Soap.VER12); // Register Marshal for "xsd:dateTime" type Marshal md = new MarshalDate (); md.register (cm);

SoapObject so = new SoapObject ("http://www.javaworld.com/ksoap/test", "transaction");

so.addProperty ("Symbol", new String ("")); so.addProperty ("Share", new Integer (0)); so.addProperty ("Buy", new Boolean (true)); so.addProperty ("Price", new SoapPrimitive ("xsd", "float", "")); cm.addTemplate (so);

SoapEnvelope envelope = new SoapEnvelope (cm); envelope.parse (xp); SoapObject orderStatus = (SoapObject) envelope.getResult();

Page 32: XML, SOAP, Services Web et JAVA Me
Page 33: XML, SOAP, Services Web et JAVA Me

Comparaison entre le package J2ME Web Services Optional Package et kXML + kSOAP

Modèle de traitement XML J2ME Web Services Optional Package

SAX seulement kXML

SAX, XMLPull et kDOM

Centré Java ou centré XML J2ME Web Services Optional Package

Traite SOAP RPC de manière similaire à RMI RPCPas de contrôle sur les messages

kXMLPlus de prise sur la structure XML interne

Page 34: XML, SOAP, Services Web et JAVA Me

Références

Enterprise J2ME

Chapitre 16

Access Web services from wireless devices, Handle SOAP messages on MIDP devices using kSOAP

http://www.javaworld.com/javaworld/jw-08-2002/jw-0823-wireless.html?page=1