JAXM – Java API for XML Messaging Daniel Kalkowski Felix Knecht Berno Löwer Matthias Maschke Christian Saga Gliederung n Einleitung q q q n n Aufbauen von SOAP Messages Nachrichtenaustausch q q n Konzept Unterschiede der Nachrichtenarten JAX-RPC vs. JAXM Direkt Über einen Provider Beispielanwendung q q Direkt Über einen Provider JAXM – Das Konzept n n Austausch von Standarddokumenten Aufteilung in: q javax.xml.messaging n n q javax.xml.soap n n n Aufbau auf SAAJ 1.1 (SOAP with Attachments API) Versenden der Nachrichten über Verbindungen Erstellung der Nachrichten (incl. Attachments) Bereitstellung von Profilen Profiles = Auf SOAP aufbauende Protokolle (z.B. ebXML) Konzeptmodell Fire And Forget n n n Sender und Empfänger können direkt weiterarbeiten Sender bekommt keine Bestätigung Wie UDP Synchrones Update n n Sender kann keine weiteren Aufgaben erledigen Sender wartet auf Bestätigung Synchrone Anfrage n n Sender kann keine weiteren Aufgaben erledigen Antwort hat nichts direkt mit der Anfrage zu tun Asynchrones Update mit Bestätigung n n Client und Server können andere Aufgabe erledigen Bestätigung der Anfrage Asynchrone Anforderung n n n Beide können andere Aufgaben erledigen Antwort kann Tage später versendet werden Antwort steht nicht in direktem Bezug zur Anfrage SOAP vs. JAXM Clients n SOAP (Standalone) n JAXM (mit Provider) Provider n n n n n n n n Versendet und empfängt Nachrichten für einen Client Client muss nicht immer laufen Routing von Nachrichten Mehrere Empfänger Unterstützt Actors Zeitlich verzögertes Senden Logging von Nachrichten Profile-Aware -> Quality-Of-Service JAX-RPC vs. JAXM n JAX-RPC kann nicht: q q q q n Attachments Nachrichten selbst bauen (Nachteil?) QoS (garantierte Versendung etc.) Nachrichten an mehrere Empfänger JAX-RPC nur auf Funktionsaufrufe ausgelegt Erstellen einer SOAPMessage mittels Java-APIs SOAP-Message ohne Attachments <?xml version="1.0" encoding="UTF-8"?> <soap-env:Envelope xmlns:soapenv="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> SOAP-Message mit Attachments ------=_Part_3_20245380.1037743827898 Content-Type: text/xml <?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> <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-- Was braucht man? n Nur ein Package: Ø javax.xml.soap Dieses ist im Java Web Services Developer Pack enthalten Aufbau einer SOAP-Message I. SOAP message A. SOAP part 1. SOAP envelope a. SOAP header (optional) b. SOAP body B. Attachment part (optional) Sowohl SOAP header, als auch Attachment parts können keiner, einer oder mehrere vorhanden sein. Auf SOAP aufsetzende Protokolle n ebXML oder SOAP-RP dafür werden extra packages von SUN bereitgestellt: com.sun.xml.messaging.jaxm.ebxml com.sun.xml.messaging.jaxm.soaprp Aufbau einer SOAP-Message ohne Attachment Quellcodeausschnitt: Erstelltes XML für Nachricht: public void createMessage(String param) { try { mf = MessageFactory.newInstance(); msg = mf.createMessage(); soapPart=msg.getSOAPPart(); envelope = soapPart.getEnvelope(); body = envelope.getBody(); <?xml version="1.0" encoding="UTF-8"?> <soap-env:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelop e/"> <soap-env:Header/> <soap-env:Body> <GetStudent> 2 </GetStudent> </soap-env:Body> </soap-env:Envelope> body.addChildElement(envelope.createNam e("GetStudent")).addTextNode(param); msg.saveChanges(); msg.writeTo(System.out); } catch (Exception ex){ System.err.println("Fehler:"+ ex); } } Wie füge ich der Nachricht ein Attachment hinzu? Hier wird ein DataHandler benutzt, um ein Bild an die Message „message“ anzuhängen: URL url = new URL("http://wombats.com/img.jpg"); AttachmentPart ap1 = message.createAttachmentPart(new DataHandler(url)); message.addAttachmentPart(ap1); Hier wird der String „hello“ als Attachment angehängt: AttachmentPart ap2 = message.createAttachmentPart("hello", charset=ISO-8859-1"); message.addAttachmentPart(ap2); "text/plain; JAVA Messaging mit XML API Package javax.xml.messaging Message Provider Connection n Interfaces q q q n OnewayListener ProviderConnection ProviderMetaData Classes q q Endpoint ProviderConnectionFactory ProviderConnectionFactory Deklaration: - public abstract class ProviderConnectionFactory Konstruktor: - public ProviderConnectionFactory() Methoden: - public abstract javax.xml.messaging.ProviderConnection createConnection() - public static javax.xml.messaging.ProviderConnectionFactory newInstance() Diese Factory bietet die Möglichkeit Verbindungen zu einem MessageProvider herzustellen. ProviderConnectionFactory Zwei Zeilen Code reichen schon aus: ProviderConnectionFactory pcf = ProviderConnectionFactory.newInstance(); ProviderConnection con = pcf.createConnection(); ProviderConnection Deklaration: - public interface ProviderConnection Methoden: - public void close() - public javax.xml.soap.MessageFactory createMessageFactory(String) - public javax.xml.messaging.ProviderMetaData getMetaData() - public 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 MessageProvider 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 int getMajorVersion() - public int getMinorVersion() - public java.lang.String getName() - public java.lang.String getSupportedProfiles() Bei bestehender Connection zu einem Provider kann der Client verschiedene Informationen über den Message Provider abrufen. ProviderMetaData Ein Codebeispiel: 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 Header der Nachricht dem Provider übergeben. Standalone Connection n Interfaces q n ReqRespListener Classes q URLEndpoint 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 dies speziell für Standalone Connections gedacht. JAXMException Deklaration: - public class JAXMException extends SOAPException Konstruktor: - public JAXMException() - public JAXMException(String) - public JAXMException(String, Throwable) - public JAXMException(Throwable) Methoden: Methoden abgeleitet von interface SOAPException - getCause() - getMessage() - initCause(Throwable) JAXMException Methoden abgeleitet von class java.lang.Throwable - fillInStackTrace - getLocalizedMessage - printStackTrace - printStackTrace - printStackTrace - toString Vorgefertigte Exceptions, die an verschiedenen Stellen „geworfen“ werden (z.B. bei der Methode send(), wenn die Nachricht nicht versandt werden kann). Die Exception muss nur noch „gefangen“ werden und verarbeitet werden. try <...> catch(throwable e) usw.