IFT604_6d_SOAP

publicité
Services Web et SOAP
Coulouris, Dollimore and Kindberg, Distributed
Systems: Concepts and Design, Edition 4, ©
Addison-Wesley 2005
Tutoriel Sun sur SAAJ
SOAP
 Initialement Simple Object Access Protocol, et dernièrement Service
Oriented Architecture Protocol
 Protocole de communication
 Communication entre applications
 Format de transmission des messages
 Communication via Internet
 Indépendant des plate-formes
 Indépendant du langage
 XML
 Simple et extensible
 Traverse les pare-feux
 Un standard W3C
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Figure 19.3 SOAP message in an envelope
envelope
header
header element
header element
body element
body element
body
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Figure 19.4 Example of a simple request without headers
env:envelope xmlns:env =namespace URI for SOAP envelopes
env:body
m:exchange
xmlns:m = namespace URI of the service description
m:arg1
Hello
m:arg2
World
In this figure and the next, each XML element is represented by a
shaded box with its name in italic followed by any attributes and its
content
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Figure 19.5 Example of a reply corresponding to the request in Figure 19.4
env:envelope xmlns:env = namespace URI for SOAP envelope
env:body
m:exchangeResponse
xmlns:m = namespace URI for the service description
m:res1
World
m:res2
Hello
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
POST /examples/stringer
endpoint address
Host: www.cdk4.net
Content-Type: application/soap+xml
Action: http://www.cdk4.net/examples/stringer#exchange
<env:envelope xmlns:env= namespace URI for SOAP envelope
>
<env:header> </env:header>
<env:body> </env:body>
</env:Envelope>
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
action
HTTP
header
Figure 19.6 Use of HTTP POST Request in SOAP client-server
communication
Règles syntaxiques
 En XML
 Doit utiliser
 SOAP Envelope namespace
 SOAP Encoding namespace
 namespace par défaut pour l’enveloppe SOAP :
 http://www.w3.org/2001/12/soap-envelope
 namespace par défaut pour encodage et les types de données SOAP :
 http://www.w3.org/2001/12/soap-encoding
 Un message SOAP ne doit pas contenir de
 référence à une DTD
 Instructions de traitement XML
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Squelette d’un message SOAP
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
SAAJ
SOAP with Attachments API for Java (SAAJ)
Manière standard de transmettre des documents XML sur
Internet en Java
http://java.sun.com/j2ee/1.4/docs/api/index.html
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Messages
Interfaces
 Node extends org.w3c.dom.Node
 SOAPEnvelope
 SOAPElement extends Node , org.w3c.dom.Element
Classes
 SOAPMessage
 SOAPPart implements org.w3c.dom.Document
Un document DOM
Many SAAJ API interfaces extend DOM interfaces
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Messages avec et sans pièces jointes
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Invocation de la méthode getLastTradePrice sur un service Web
 REQUETE
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<m:GetLastTradePrice
xmlns:m="http://wombat.ztrade.com">
<symbol>SUNW</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
 REPONSE
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Construction d’une requête SOAP
import javax.xml.soap.*;
import java.util.*;
import java.net.URL;
public class SoapRequest {
public static void main(String[] args) {
try {
SOAPConnectionFactory soapConnectionFactory =
SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConnectionFactory.createConnection();
SOAPFactory soapFactory = SOAPFactory.newInstance();
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPHeader header = message.getSOAPHeader();
SOAPBody body = message.getSOAPBody();
header.detachNode();
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Construction d’une requête SOAP
Name bodyName = soapFactory.createName("GetLastTradePrice", "m",
"http://wombats.ztrade.com");
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
Name name = soapFactory.createName("symbol");
SOAPElement symbol = bodyElement.addChildElement(name);
symbol.addTextNode("SUNW");
URL endpoint = new URL("http://wombat.ztrade.com/quotes");
SOAPMessage response = connection.call(message, endpoint);
connection.close();
SOAPBody soapBody = response.getSOAPBody();
Iterator iterator = soapBody.getChildElements(bodyName);
bodyElement = (SOAPBodyElement) iterator.next();
String lastPrice = bodyElement.getValue();
System.out.print("The last price for SUNW is ");
System.out.println(lastPrice);
} catch (Exception ex) { ex.printStackTrace();
}
}
}
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Connexions
 Tous les messages SOAP sont transmis et reçus à l’aide d’une
connexion.
 Messages de type request-response.
 méthode call, bloquantes en attente d’une réponse
SOAPConnectionFactory soapConnectionFactory;
SOAPConnection connection;
URL endpoint;
SOAPMessage response;
soapConnectionFactory = SOAPConnectionFactory.newInstance();
connection = soapConnectionFactory.createConnection();
...// create a request message and give it content
endpoint = new URL("http://wombat.ztrade.com/quotes");
response = connection.call(message, endpoint);
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Création d’une connexion
import javax.xml.soap.*;
import java.util.*;
import java.net.URL;
public class SoapRequest {
public static void main(String[] args) {
SOAPConnectionFactory soapConnectionFactory;
SOAPConnection connection;
SOAPFactory soapFactory;
try {
soapConnectionFactory = SOAPConnectionFactory.newInstance();
connection = soapConnectionFactory.createConnection();
soapFactory = SOAPFactory.newInstance();
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Création d’un message
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
// header : données XML qui affecte la manière dont le contenu
// spécifique à une application sera traité par le fournisseur du
// message, par exemple : sémantique d’une transaction, information
SOAPHeader header = message.getSOAPHeader();
SOAPBody body = message.getSOAPBody();
// l’en-tête n’est pas nécessaire
header.detachNode();
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Création d’un message
 L’instance de SOAPFactory permet de créer les différents objets qui
seront dans l’arborescence XML SOAP
 createName(String localName, String prefix, String uri)
Name bodyName = soapFactory.createName( "GetLastTradePrice",
"m",
"http://wombats.ztrade.com");
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
Name name = soapFactory.createName("symbol");
SOAPElement symbol = bodyElement.addChildElement(name);
symbol.addTextNode("SUNW");
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Le message SOAP résultant
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns:m="http://wombat.ztrade.com">
<symbol>SUNW</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Envoi du message
URL endpoint ;
SOAPMessage response;
endpoint = new URL("http://wombat.ztrade.com/quotes");
response = connection.call(message, endpoint);
connection.close();
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Analyse de la réponse
SOAPBody soapBody = response.getSOAPBody();
Iterator iterator = soapBody.getChildElements(bodyName);
bodyElement = (SOAPBodyElement) iterator.next();
String lastPrice = bodyElement.getValue();
System.out.print("The last price for SUNW is ");
System.out.println(lastPrice);
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Création d’une pièce jointe de type texte
AttachmentPart attachment = message.createAttachmentPart();
String stringContent = "Update address for Sunny Skies "
+
"Inc., to 10 Upbeat Street, Pleasant Grove, CA 95439";
attachment.setContent(stringContent, "text/plain");
attachment.setContentId("update_address");
message.addAttachmentPart(attachment);
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Création d’une pièce jointe de type image
URL url = new URL("http://greatproducts.com/gizmos/img.jpg");
DataHandler dataHandler = new DataHandler(url);
AttachmentPart attachment = message.createAttachmentPart(dataHandler);
attachment.setContentId("attached_image");
message.addAttachmentPart(attachment);
 Le DataHandler va s’occuper de déterminer le type MIME
 setContentID : déterminer le nom qui sera utilisé pour identifier la pièce jointe
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Accéder aux pièces jointes
java.util.Iterator iterator = message.getAttachments();
while (iterator.hasNext()) {
AttachmentPart attachment = (AttachmentPart)iterator.next();
String id = attachment.getContentId();
String type = attachment.getContentType();
System.out.print("Attachment " + id
+ " has content type " + type);
if (type == "text/plain") {
Object content = attachment.getContent();
System.out.println("Attachment " + "contains:\n" + content);
}
}
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Attributs de l’en-tête
Détermine comment le destinataire doit traiter le
message
Façon d’étendre un message en donnant de
l’information sur des éléments comme
authentification, gestion des transactions, paiement
etc.
Attributs de l’en-tête (SOAP 1.1)
actor
mustUnderstand
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Attribut actor
 Indique le destinataire de l’élément header
 Par défaut, le destinataire ultime
 Un acteur est une application qui peut
Recevoir des messages SOAP
Les acheminer à un autre acteur
 Exemple : traitement d’un bon de commande
Route: order desk, shipping desk, confirmation desk, billing department.
Chaque application prend les actions nécessaires, retire les objets
pertinents pour son travail, achemine le message à l’acteur suivant
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Chaîne d’acteurs
SOAPHeader header = message.getSOAPHeader();
SOAPFactory soapFactory = SOAPFactory.newInstance();
String nameSpace = "ns";
String nameSpaceURI = "http://gizmos.com/NSURI";
Name order = soapFactory.createName("orderDesk", nameSpace, nameSpaceURI);
SOAPHeaderElement orderHeader =
header.addHeaderElement(order);
orderHeader.setActor("http://gizmos.com/orders");
Name shipping =
soapFactory.createName("shippingDesk",nameSpace, nameSpaceURI);
SOAPHeaderElement shippingHeader = header.addHeaderElement(shipping);
shippingHeader.setActor("http://gizmos.com/shipping");
Name confirmation = soapFactory.createName("confirmationDesk",nameSpace, nameSpaceURI);
SOAPHeaderElement confirmationHeader = header.addHeaderElement(confirmation);
confirmationHeader.setActor( "http://gizmos.com/confirmations");
Name billing = soapFactory.createName("billingDesk", nameSpace, nameSpaceURI);
SOAPHeaderElement billingHeader = header.addHeaderElement(billing);
billingHeader.setActor("http://gizmos.com/billing");
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Attribut mustUnderstand
 Indique si oui ou non le destinataire doit savoir traiter les en-têtes
SOAPHeader header = message.getSOAPHeader();
Name name = soapFactory.createName("Transaction",
"t","http://gizmos.com/orders");
SOAPHeaderElement transaction = header.addHeaderElement(name);
transaction.setMustUnderstand(true);
transaction.addTextNode("5");
 Fichier résultant
<SOAP-ENV:Header>
<t:Transaction
xmlns:t="http://gizmos.com/orders"
SOAP-ENV:mustUnderstand="1">
5
</t:Transaction>
</SOAP-ENV:Header>
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Fautes
Si un message n’a pas réussi
Un seul élément « faute » par message SOAP
Doit être dans le corps (body) du message SOAP.
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
SOAPFault fault = body.addFault();
Name faultName = soapFactory.createName("Client", "", SOAPConstants.URI_NS_SOAP_ENVELOPE);
fault.setFaultCode(faultName);
fault.setFaultString("Message does not have necessary info");
Detail detail = fault.addDetail();
Name entryName = soapFactory.createName("order",
"PO", "http://gizmos.com/orders/");
DetailEntry entry = detail.addDetailEntry(entryName);
entry.addTextNode("Quantity element does not have a value");
Name entryName2 = soapFactory.createName("confirmation",
DetailEntry entry2 = detail.addDetailEntry(entryName2);
entry2.addTextNode("Incomplete address: no zip code");

"PO", "http://gizmos.com/confirm");
Fichier résultant
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Message does not have necessary info</faultstring>
<faultactor>http://gizmos.com/order</faultactor>
<detail>
<PO:order xmlns:PO="http://gizmos.com/orders/">
Quantity element does not have a value
</PO:order>
<PO:confirmation xmlns:PO="http://gizmos.com/confirm">
Incomplete address: no zip code
</PO:confirmation>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Récupérer la faute
SOAPBody body = newMessage.getSOAPBody();
if ( body.hasFault() ) {
SOAPFault newFault = body.getFault();
Name code = newFault.getFaultCodeAsName();
String string = newFault.getFaultString();
String actor = newFault.getFaultActor();
System.out.println("SOAP fault contains: ");
System.out.println(" Fault code = " +
code.getQualifiedName());
System.out.println(" Fault string = " + string);
if ( actor != null ) {
System.out.println(" Fault actor = " + actor);
}
Detail newDetail = newFault.getDetail();
if (newDetail != null) {
Iterator entries = newDetail.getDetailEntries();
while ( entries.hasNext() ) {
DetailEntry newEntry =
(DetailEntry)entries.next();
String value = newEntry.getValue();
System.out.println(" Detail entry = " + value);
}
}

Output
SOAP fault contains:
Fault code = SOAP-ENV:Client
Local name = Client
Namespace prefix = SOAP-ENV, bound to
http://schemas.xmlsoap.org/soap/envelope/
Fault string = Message does not have necessary info
Fault actor = http://gizmos.com/order
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design
Detail entry = Quantity element does not ©have
a value
Addison-Wesley
Publishers 2005
Detail entry = Incomplete address: no zip code
Edn. 4
Références
J2EE 1.5 tutorial
Chapter 19
SOAP with Attachments API for Java
http://java.sun.com/javaee/5/docs/tutorial/doc/bnbhf.html
Instructor’s Guide for Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edn. 4
© Addison-Wesley Publishers 2005
Téléchargement