JAXM – Java API for XML Messaging

Werbung
JAXM – Java API for XML Messaging
Ein Referat von
Daniel Kalkowski
Felix Knecht
Berno Löwer
Matthias Maschke
Christian Saga
Gliederung
-
-
Einleitung
o Konzept
o Unterschiede der Nachrichtenarten
o Standalone vs. Provider
o JAX-RPC vs. JAXM
Aufbau von SOAP-Nachrichten
API für das Erstellen von SOAP-Nachrichten
API für das Versenden von SOAP-Nachrichten
o Mit Provider
o Standalone
o Exception-Klasse
JAXM – Das Konzept
Bei JAXM geht es um den Austausch von Standarddokumenten.
Für JAXM werden zwei Packages benötigt.
Zum einen gibt es das Package javax.xml.soap. Dieses Package dient zum erstellen von
SOAP-Nachrichten mit und ohne Attachments. Außerdem stellt dieses Package Profile bereit.
Profile sind auf SOAP aufbauende Protokolle wie zum Beispiel ebXML.
Zum anderen gibt es das javax.xml.messaging Packages, welches für den Aufbau von
Verbindungen und das Versenden der SOAP-Nachrichten über diese Verbindungen zuständig
ist. Es baut auf SAAJ 1.1 (SOAP with Attachments API) auf.
JAXM – Konzeptmodell
JAXM ist eine leichtgewichtige MessagingAPI zur Entwicklung von XML basierten
Business-Applikationen.
Diese Applikationen dienen überwiegend
zum
Austausch
von
elektronischen
Geschäftsdokumenten zwischen Unternehmen.
Die Austausch-Szenarios, die auf JAXM
basieren, sind immer Dokumenten- zentriert
und fallen in fünf große Kategorien, die in
den folgenden Abschnitten beschrieben
werden.
Fire And Forget
Bei dieser Übertragungsmethode versendet der Sender die Nachricht an den Empfänger ohne
danach auf eine Antwort oder eine Bestätigung zu warten. Der Sender kann also direkt nach
dem Versenden der Nachricht weiterarbeiten. Diese Übertragungsmethode ist relativ unsicher,
da für den Sender nicht sichergestellt ist, dass die Nachricht korrekt übertragen und
verarbeitet wurde.
Synchrones Update
Bei dieser Übertragungsmethode versendet der Sender eine Nachricht an den Empfänger und
wartet auf eine Bestätigung der Nachricht durch den Empfänger. Der Sender kann also in der
Zeit zwischen Versand der Nachricht und dem Empfang der Bestätigung keine anderen
Aufgaben wahrnehmen. Er blockiert.
Eine korrekte Übertragung der Daten und eine Bearbeitung kann dadurch für den Sender
sichergestellt werden, da er eine Bestätigung erhält.
Synchrone Anfrage
Bei dieser Übertragungsmethode sendet der Sender eine Nachricht an den Empfänger und
erhält nach Verarbeitung der Nachricht durch den Empfänger eine vollwertige Antwort
zurück (im Gegensatz zur einfachen Bestätigung wie beim Synchronen Update). Diese
Antwortnachricht muss nicht direkt mit der gesendeten Anfrage zu tun haben.
Asynchrones Update mit Bestätigung
Bei dieser Übertragungsmethode kann der Sender nach dem Versand der Nachricht
weiterarbeiten während der Empfänger die Nachricht bearbeitet. Wenn der Empfänger fertig
ist, sendet er eine einfache Bestätigung an den Sender, die dieser dann verarbeiten kann.
Asynchrone Anforderung
Bei dieser Übertragungsmethode kann der Sender wie beim asynchronen Update mit
Bestätigung nach dem Versand der Nachricht weiterarbeiten während der Empfänger die
Nachricht bearbeitet. Wenn der Empfänger fertig ist, sendet er eine vollwertige Nachricht an
den Sender, die dieser dann verarbeiten kann. Diese Antwortnachricht kann auch mehrere
Tage nach dem Versand der Anfrage versendet werden und muss keinen direkten Bezug zu
der gesendeten Anfrage haben.
SOAP vs. JAXM Clients
Im Standalone- Betrieb kommuniziert der Sender direkt
mit dem Empfänger. Er versendet seine Nachrichten
direkt an den Empfänger und erhält von diesem direkt
eine Antwort.
In Verbindung mit einem Message-Provider kann der
Sender die Nachricht seinem Provider übergeben, der
sie dann an den Provider des Empfängers übergibt.
Dieser übergibt die Nachricht dann an den Empfänger.
Der Empfänger über gibt seine Antwortnachricht an
seinen Provider, der sie dann an den Provider des
Senders übergibt. Dieser leitet sie dann an den Sender
weiter. Dieses Verfahren hat den Vorteil, dass weder der
Sender noch der Empfänger permanent laufen bzw.
empfangsbereit sein müssen. Sie erhalten die für sie bestimmten Nachrichten von ihrem
Provider, wenn sie dazu bereit sind. Dieses Verfahren entspricht in seiner Vorgehensweise
dem Versand und Empfang von e-Mails über SMTP und POP3.
Provider
Ein JAXM-Provider ist ein Programm, das entweder auf dem gleichen oder auf einem
anderen Rechner als der Client läuft. Dieses Programm versendet und Empfängt Nachrichten
für den Client. Dies bedeutet, dass Nachrichten, die eintreffen währende der Client nicht läuft,
nicht verloren gehen. Sie werden beim Provider gespeichert, bis der Client wieder läuft bzw.
eine Verbindung zum Provider aufgebaut hat und sie abholt.
Der Provider kümmert sich beim Versand der Nachrichten auch um das Routing und
unterstützt dabei Actors (Stationen zwischen den Providern von Sender und Empfänger à
siehe SOAP-Referat).
Er ermöglicht auch den Nachrichtenversand an mehrere Empfänger und zeitlich verzögertes
Senden, wobei der sendende Client nicht auf den Versand warten muss, sondern beendet
werden kann.
Ferner kann ein Provider auch den Nachrichtenversand und –empfang protokollieren
(Logging).
Außerdem kann der Provider die zu versendenden Nachrichten auf andere Profile (z.B.
ebXML) umsetzten. Diese Umsetztung erfolgt für den Client transparent. Er braucht sich also
weder darum zu kümmern noch bemerkt er davon etwas.
JAX-RPC vs. JAXM
Der Vorteil von JAX-RPC gegenüber JAXM ist, dass JAX-RPC in der Handhabung
wesentlich einfacher ist als JAXM, da man sich bei JAX-RPC nicht wie bei JAXM selbst um
den Aufbau der SOAP-Nachrichten kümmern muss. Dies wird von der API übernommen.
Ein Nachteil von JAX-RPC gegenüber JAXM ist, dass JAX-RPC ausschließlich auf
Funktionsaufrufe ausgelegt ist, während JAXM zur Übertragung von Daten, auch Binärdaten
wie z.b. Bildern, dient. Diese Daten können als Attachments an die SOAP-Nachrichten
angehängt werden.
Ein weiterer Unterschied zwischen AJXM und JAX-RPC ist, dass eine Nachricht bei JAXM
mehrere Empfänger haben kann. Bei JAX-RPC nur einen.
Ferner ist bei JAX-RPC die Versendung der Nachrichten nicht gesichert.
Erstellen einer SOAP-Nachricht mittels Java-APIs
Zum Erstellen von SOAP-Nachrichten in Java benötigt man nur ein Package: javax.xml.soap.
Dieses Package ist im Java Web Services Developer Pack enthalten (http://java.sun.com).
Eine normale SOAP-Nachricht besteht aus einem SOAP-Part, der den SOAP-Envelope
enthält. Dieser enthält den SOAP-Header und den SOAP-Body. Eine SOAP-Nachricht mit
Attachment, wie sie mit JAXM erstellt und versandt werden kann, enthält neben dem
normalen SOAP-Part einen oder mehrere Attachment-Parts nach dem SOAP-Part. Jeder
Attachment-Part hat einen MIME-Header uns einen Content (Inhalt). Dieser Inhalt kann XML
sein, muss aber nicht. Er kann mit entsprechenden Angaben im Mime-Header auch
Binärdaten (z.B. ein Bild) enthalten.
Beispiele:
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env=
"http://schemas.xmlsoap.org/soap/envelope/"
>
<soap-env:Header/>
<soap-env:Body>
<Students>
<Vorname>Christian</Vorname>
<Vorlesung>Projektseminar</Vorlesung>
<Note>1</Note>
</Students>
</soap-env:Body>
</soap-env:Envelope>
------=_Part_3_20245380.1037743827898
Content-Type: text/xml
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body>
<ztrade:GetLastTradePrice
xmlns:ztrade="http://wombat.ztrade.com">
<ztrade:symbol>SUNW</ztrade:symbol>
</ztrade:GetLastTradePrice>
</soap-env:Body>
</soap-env:Envelope>
------=_Part_3_20245380.1037743827898
Content-Type: text/html
<html>
<body>
This is a simple example of a roundtrip JAXM
message exchange.
<p> Click <a href="sender">here</a> to send the
message
</body>
</html>
------=_Part_3_20245380.1037743827898--
Aufbau einer SOAP-Nachricht
SOAP message
A. SOAP part
1. SOAP envelope
a. SOAP header (optional)
b. SOAP body
B. Attachment part (optional)
Sowohl der SOAP-Header, als auch der Attachment-Part können null-, ein- oder mehrmals
vorhanden sein. Nur der SOAP-Body darf nicht fehlen.
Auf SOAP aufsetzende Protokolle
Um mit auf SOAP aufsetzenden Protokolle wie ebXML und SOAP-RP arbeiten zu können,
hat SUN entsprechende Packages zur Verfügung gestellt:
com.sun.xml.messaging.jaxm.ebxml
com.sun.xml.messaging.jaxm.soaprp
Auf diese Protokolle wird hier nicht näher eingegangen.
Aufbau einer SOAP-Nachricht ohne Attachment
Um eine neue Message zu erzeugen, benötigt man zuerst eine Instanz der MessageFactory.
Diese erhält man mit MessageFactory.newInstance().
Mit dieser MessageFactory
mf.createMessage().
erzeugt
man
dann
ein
SOAPMessage-Objekt
Über den Aufruf msg.getSOAPPart() erhält man den in der Message enthaltenen
soapPart als Objekt.
Von diesem Objekt erhält man mit soapPart.getEnvelope() den SOAP-Enevelope
und mit envelope.getBody() den darin enthaltenen SOAP-Body.
Jetzt
kann
man
mit
body.addChildElement(envelope.CreateName
("GetStudent")).addTextNode(param) dem Body ein Element mit enthaltenem
Text hinzufügen.
Mit msg.saveChanges() speichert man alle Änderungen (hier das neue Element im
SOAP-Body) in dem SOAPMessage-Objekt.
Jetzt kann die SOAP-Nachricht versandt werden.
Der Zugriff auf die einzelnen Teile einer SOAPMessage geschieht also von außen nach innen
entlang der XML-Struktur der SOAPMessage.
Aufbau einer SOAP-Nachricht ohne Attachment
Beispiel:
Quellcodeausschnitt:
public void createMessage(String param)
{
try
{
mf = MessageFactory.newInstance();
msg = mf.createMessage();
soapPart=msg.getSOAPPart();
envelope = soapPart.getEnvelope();
body = envelope.getBody();
body.addChildElement(envelope.
createName("GetStudent")).
addTextNode(param);
msg.saveChanges();
msg.writeTo(System.out);
}
catch (Exception ex)
{
System.err.println("Fehler:"+ ex);
}
}
Erstelltes XML für die Nachricht:
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body>
<GetStudent>
2
</GetStudent>
</soap-env:Body>
</soap-env:Envelope>
Hinzufügen eines Attachments
Zum Anhängen einer Datei als Attachment an eine SOAPMessage benutzt man einen
DataHandler:
URL url = new URL("http://wombats.com/img.jpg");
AttachmentPart ap1 = message.createAttachmentPart(new DataHandler(url));
message.addAttachmentPart(ap1);
Um einen String als Attachment anzuhängen, benötigt man den DataHandler nicht:
AttachmentPart ap2 = message.createAttachmentPart("hello", "text/plain;
charset=ISO-8859-1");
message.addAttachmentPart(ap2);
JAVA Messaging mit XML API
Zum Versenden der SOAP-Nachrichten benötigt man das Package javax.xml.messaging.
Dieses Package enthält die Klassen Endpoint und ProviderConnectionFactory und die
Interfaces OnewayListener, ProviderConnection und ProviderMetaData für Verbindungen mit
Provider.
Für Verbindungen ohne Provider (Standalone) gibt es die Klasse URLEndpoint und das
Interface ReqRespListener.
Für beide Arten von Verbindungen gibt es noch JAXMException als Exception-Klasse.
ProviderConnectionFactory
Deklaration:
public abstract class ProviderConnectionFactory
Konstruktor:
public ProviderConnectionFactory()
Methoden:
public abstract javax.xml.messaging.ProviderConnection createConnection()
Mit dieser Methode werden ProviderConnections erzeugt.
public static javax.xml.messaging.ProviderConnectionFactory newInstance()
Mit dieser Methode wird eine Instanz der ProviderConnectionFactory erzeugt.
Diese Factory bietet die Möglichkeit Verbindungen zu einem MessageProvider herzustellen.
Um die ProviderConnectionFactory zu verwenden, werden nur zwei Zeilen Code benötigt:
ProviderConnectionFactory pcf = ProviderConnectionFactory.newInstance();
ProviderConnection con = pcf.createConnection();
ProviderConnection
Deklaration:
public interface ProviderConnection
Methoden:
public
public
public
public
void close()
javax.xml.soap.MessageFactory createMessageFactory(String)
javax.xml.messaging.ProviderMetaData getMetaData()
void send()
Die ProviderConnection ist eine aktive Verbindung eines Clients zu einem Provider. Sie
enthält alle Methoden um Nachrichten zu versenden.
OnewayListener
Deklaration:
public interface OnewayListener
Methoden:
public void onMessage(SOAPMessage)
Der OnewayListener muss bei Verbindungen über einen Message-Provider eingerichtet
werden, da die Nachrichten über den Provider nach dem Prinzip fire-and- forget versandt
werden.
Will man auf einen Response reagieren muss dieser Listener nun eingerichtet werden.
ProviderMetaData
Deklaration:
public interface ProviderMetaData
Methoden:
public
public
public
public
int getMajorVersion()
int getMinorVersion()
java.lang.String getName()
java.lang.String getSupportedProfiles()
Bei bestehender Connection zu einem Provider kann der Client verschiedene Informationen
über den Message-Provider abrufen.
Beispiel:
ProviderMetaData pmd = con.getMetaData();
String name = pmd.getName();
int majorVersion = pmd.getProviderMajorVersion();
int minorVersion = pmd.getProviderMinorVersion();
Endpoint
Deklaration:
public class Endpoint
Konstruktor:
public Endpoint (String)
Methoden:
public java.lang.String toString()
Der Endpoint repräsentiert eine Adresse eines Servicepartners. Diese wird im SOAP-Header der
Nachricht dem Provider übergeben.
ReqRespListener
Deklaration:
public interface ReqRespListener
Methoden:
public.javax.xml.soap.SOAPMessage onMessage(SOAPMessage)
Bei Standalone Connections wird der Sender nach dem call Aufruf geblockt, bis ein Response
eintrifft.
Der ReqRespListener regelt die Verarbeitung der Response Message. Wird kein Response
erwartet, muss trotzdem ein ReqRespListener eingesetzt werden und eine leere Nachricht an
onMessage geschickt werden, um die Blockierung durch call aufzulösen.
URLEndpoint
Deklaration:
public class URLEndpoint extends Endpoint
Konstruktor:
public URLEndpoint(String)
Methoden:
public.java.lang.String getURL()
URLEndpoint ist eine Unterklasse von Endpoint und erfüllt die selben Aufgaben
(Adressauflösung). Nur ist URLEndpoint speziell für Standalone–Verbind ungen gedacht.
JAXMException
Deklaration:
public class JAXMException extends SOAPException
Konstruktor:
public
public
public
public
JAXMException()
JAXMException(String)
JAXMException(String, Throwable)
JAXMException(Throwable)
Methoden:
getCause()
getMessage()
initCause(Throwable)
Diese Methoden von JAXMException sind vom Interface SOAPException abgeleitet.
Folgende Methoden sind von class java.lang.Throwable abgeleitet:
fillInStackTrace
getLocalizedMessage
printStackTrace
printStackTrace
printStackTrace
toString
JAXMException
Es gibt auch vorgefertigte Exceptions, die an verschiedenen Stellen „geworfen“ werden. Zum
Beispiel in der Methode send(), wenn die Nachricht nicht versandt werden kann. Hier braucht
man sich nicht um die Erstellung und das werfen von Exceptions zu kümmern. Die Exception
muss nur noch „gefangen“ werden und verarbeitet werden.
try
{...}
catch(throwable e)
{...}
Quellangaben
-
Java Web Services Tutorial 1.0 (http://java.sun.com/webservices/tutorial.html)
Java Web Services Documentation (http://java.sun.com/webservices/docs.html)
Java Web Services Developer Pack API Specification
(http://java.sun.com/webservices/docs/1.0/api/index.html)
JAXM Specifications (http://java.sun.com/xml/downloads/jaxm.html)
Sun Web Services Developer Code Camp
(http://fr.sun.com/developpeurs/sdc/webservices/)
Herunterladen