Hinweis:
Aus Platzgründen wurden in diesem Artikel die umfangreichen Quellcodes nur auszugsweise abgedruckt. Sämtliche Quellcodes, auf die sich der Autor bezieht, befinden sich aber auf der beiliegenden CD. Zum Nachvollziehen der Beispiele empfehlen wir, die Quellcodes vollständig auszudrucken.Die Red.
JDOM
Einer der Vorteile der Standard-APIs in XML ist deren sprachenübergreifende Verfügbarkeit. Vielleicht fällt Ihnen bei den Beispielen der vorigen Folgen dieser Serie auf, dass die meisten Bibliothek-importe mit org.w3c.* oder org.xml.* beginnen. SAX und DOM sind Standard-APIs, die vom World Wide Web Consortium (W3C) und anderen Standardisierungsorganen entwickelt wurden. Das ist besonders angenehm, wenn Sie Code in mehr als einer Sprache schreiben, der XML verarbeiten muss - Sie können dann dieselbe API in Java verwenden, die Sie auch in C++ oder Perl benutzen. Da sie von einem Standardisierungsorgan definiert werden, sind sie über alle unterstützte Sprachen konsistent.Einer der größten Nachteile der Standard-APIs ist jedoch deren sprachenübergreifende Verfügbarkeit! Das Problem dabei besteht darin, dass jede der APIs ihre gesamten Datenstrukturen von Grundprinzipien aus definieren muss. Anders ausgedrückt, das Standardisierungsorgan kann aus keinen Standardmerkmalen der Sprache Vorteile ziehen, da sie sie auf diesen sprachenübergreifenden Standard überschreiben. Dies zeigt sich besonders deutlich im DOM-API für Komponentensammlungen. DOM definiert Datenstrukturen wie NamedNodeMap für die Handhabung von Sammlungen. Wenn Sie Java verwenden, wäre es natürlich angenehm, wenn Sie die Java-Standardsammlungen (wie Maps, Lists usw.) verwenden könnten. Jedoch kann die DOM-API nicht auf diese Merkmale der Java-Sprache überschrieben werden. Hier ist eine Reihe von Klassen erforderlich, die die Standard-APIs unterstützen, aber auch Java-Standardkonstruktionen nutzen.
Genau darum geht es bei JDOM. JDOM ist kein Akronym (genauso wie JDBC technisch kein Akronym ist); es ist eine Open-Source-Bibliothek mit XML-Verarbeitungscode, der die XML-Standard-APIs unterstützt, aber Java-spezifisch. In anderen Worten, Sie können SAX und DOM nur mit Java-Standardsammlungen verwenden. JDOM ist über die Internetadresse www.jdom.org erhältlich. Es ist ein Projekt mit offenem Quellcode, das beim Abfassen dieses Artikels als Beta-Version vorlag. Die Autoren versuchen damit, eine Alternative mit völlig offenem Quellcode zu den Standard-APIs für Java-Entwicker zu schaffen. JDOM verwendet die gleiche Lizenz für offenen Quellcode wie der Apache-Webserver (das bedeutet, jeder kann es verwenden, ohne auch sein Produkt zu offenem Quellcode zu machen). Es unterstützt SAX, DOM, Validierungen, XSLT-Konvertierungen und weitere XML-Merkmale.
Listing 1
<?xml version="1.0" encoding="UTF-8"?><Configuration><Position left="100" top="100"/><Visuals title="default title"/></Configuration>
package xmlconfig;import java.io.*;import java.util.*;import java.net.*;import org.w3c.dom.*;import org.apache.xerces.dom.DocumentImpl;import org.apache.xerces.dom.DOMImplementationImpl;import org.w3c.dom.Document;import org.apache.xml.serialize.OutputFormat;import org.apache.xml.serialize.Serializer;import org.apache.xml.serialize.SerializerFactory;import org.apache.xml.serialize.XMLSerializer;import org.apache.xerces.parsers.DOMParser;public class Configuration {private Configuration() throws NoConfigFileException {//-- load configuration infoloadConfig();}static public Configuration getConfiguration()throws NoConfigFileException {if (myConfig == null) {myConfig = new Configuration();}return(myConfig);}private void loadConfig() throws NoConfigFileException {System.out.print("Parsing XML File: " +CONFIG_FILE_NAME + "...");DOMParser parser = new DOMParser();try {parser.parse(CONFIG_FILE_URI);Document doc = parser.getDocument();recurseDOMTree(doc);} catch (Exception e) {e.printStackTrace();System.out.println("Error in parsing: " +e.getMessage());}System.out.println("Done.");}public void recurseDOMTree(Node node) {switch (node.getNodeType()) {case Node.ELEMENT_NODE:String name = node.getNodeName();NamedNodeMap attributes = node.getAttributes();if (name.equalsIgnoreCase("position")) {top = Integer.parseInt(attributes.getNamedItem("top").getNodeValue());left = Integer.parseInt(attributes.getNamedItem("left").getNodeValue());} else if (name.equalsIgnoreCase("visuals")) {title = attributes.getNamedItem("title").getNodeValue();} //elsebreak;} //switch//-- recurse on each childNodeList children = node.getChildNodes();if (children != null) {for (int i=0; i<children.getLength(); i++) {recurseDOMTree(children.item(i));} //for} //if}public static void main(String[] args) {System.out.print("Building default configuration file at "+ CONFIG_FILE_NAME + "...");Document doc = new DocumentImpl();Element root = doc.createElement("Configuration");Element posElem = doc.createElement("Position");posElem.setAttribute("left", "100");posElem.setAttribute("top", "100");root.appendChild(posElem);Element titleElem = doc.createElement("Visuals");titleElem.setAttribute("title", "default title");root.appendChild(titleElem);doc.appendChild(root);OutputFormat format = new OutputFormat(doc);StringWriter stringOut = new StringWriter();XMLSerializer serial = new XMLSerializer(stringOut, format);FileWriter fw = null;try {serial.asDOMSerializer();serial.serialize(doc.getDocumentElement());fw = new FileWriter(CONFIG_FILE_NAME);fw.write(stringOut.toString());} catch (IOException ioex) {ioex.printStackTrace();} finally {try {fw.flush();fw.close();} catch (IOException ignored) {} //catch} //finallySystem.out.println("Done.");}public void setTop(int newTop) {top = newTop;}public int getTop() {return(top);}public void setLeft(int newLeft) {left = newLeft;}public int getLeft() {return(left);}public void setTitle(String newTitle) {title = newTitle;}public String getTitle() {return(title);}static private Configuration myConfig;static public final String CONFIG_FILE_NAME ="c:/data/dom_config.xml";static private final String CONFIG_FILE_URI ="file://localhost/" + CONFIG_FILE_NAME;private static final String DEFAULT_DOM_ADAPTER_CLASS ="org.jdom.adapters.XercesDOMAdapter";private int top;private int left;private String title;}class NoConfigFileException extends IOException {NoConfigFileException() {super();}NoConfigFileException(String msg) {super(msg);}}
Der andere erwähnenswerte Code in diesem Beispiel ist die Methode loadConfig(), der für DOM-Code in Java auch sehr typisch ist. Sie parsen das Dokument unter Verwendung eines DOM-Parsers (in diesem Fall Xerces) und übergeben das Dokument an eine Methode, um Informationen herauszuholen. Die Methode recurseDOMTree() wird Ihnen sehr vertraut erscheinen, wenn Sie schon sehr viel mit DOM-Dokumenten gearbeitet haben. Sie müssen den Baum rekursiv abarbeiten und dabei die Elemente herausziehen, an denen Sie interessiert sind.
Listing 3
. . .public static void main(String[] args) {System.out.print("Building default configuration file at "+ CONFIG_FILE_NAME + "...");DOMBuilder builder = new DOMBuilder(DEFAULT_DOM_ADAPTER_CLASS);Element root = new Element("Configuration");Element posElem = new Element("Position");posElem.addAttribute("left", "100");posElem.addAttribute("top", "100");root.addContent(posElem);Element titleElem = new Element("Visuals");titleElem.addAttribute("Title", "Default Title");root.addContent(titleElem);Document doc = new Document(root);FileOutputStream fos = null;try {fos = new FileOutputStream(CONFIG_FILE_NAME);XMLOutputter outputter = new XMLOutputter();outputter.output(doc, fos);} catch (IOException ioe) {ioe.printStackTrace();} finally {try {fos.flush();fos.close();} catch (IOException ignored) {} //catch} //finallySystem.out.println("done.");}. . .private void loadConfig()throws NoConfigFileException, JDOMException {DOMBuilder builder = new DOMBuilder(DEFAULT_DOM_ADAPTER_CLASS);FileInputStream in = null;try {in = new FileInputStream(CONFIG_FILE_NAME);//build a DOM tree with the specified or default parserDOMAdapter domAdapter;Class parserClass = Class.forName(DEFAULT_DOM_ADAPTER_CLASS);domAdapter = (DOMAdapter)parserClass.newInstance();//-- Build the JDOM Documentorg.w3c.dom.Document w3cdoc =domAdapter.getDocument((InputStream)in, false);Document doc = builder.build(w3cdoc);//-- Print out entire set of attributesElement elem = doc.getRootElement();java.util.List lst = elem.getChildren();Iterator it = lst.iterator();while (it.hasNext()) {Element e = (Element) it.next();java.util.List child = e.getAttributes();Iterator i = child.iterator();while (i.hasNext()) {Attribute attr = (Attribute) i.next();System.err.println(attr.getName() + " : " +attr.getValue() );}}//-- get config info for propertiestop = Integer.parseInt(elem.getChild("Position").getAttribute("top").getValue());left = Integer.parseInt(elem.getChild("Position").getAttribute("left").getValue());title = elem.getChild("Visuals").getAttribute("Title").getValue();} catch (ClassNotFoundException e) {throw new JDOMException("Parser class " +DEFAULT_DOM_ADAPTER_CLASS + " not found");} catch (IOException ioe) {ioe.printStackTrace();} catch (Exception e) {throw new JDOMException("Parser class " + DEFAULT_DOM_ADAPTER_CLASS +" instantiation error");} finally {try {in.close();} catch (IOException ignored) {} //catch}}
Die Methode loadConfig() leistet hier mehr Arbeit als in der früheren Version mit viel weniger Code. Die zuerst erledigte Aufgabe besteht im Laden des XML-Dokuments und dieser Prozess ist dem DOM-Code sehr ähnlich. Als nächstes drucke ich die Liste aller Attribute aus. Achten Sie hier auf den Einsatz einer java.util.List und eines java.util.Iterator. JDOM-Sammlungen verwenden das System der Java-Standardsammlungen, um Aufgaben wie das Iterieren durch alle Elemente eines Baumes zu vereinfachen. Zuletzt ermöglicht JDOM es Ihnen, einen Direktzugriff auf die Elemente des Baums vorzunehmen. Anstatt eine Parsing-Routine zu schreiben, können Sie also Code wie den folgenden verwenden:
elem.getChild("Position").getAttribute("top").getValue());
In Listing 4 (zu finden auf der beiliegenden CD) sehen Sie weiteres Beispiel dafür, wie leicht der Einsatz von JDOM ist. Es handelt sich um eines der Beispiele, das mit JDOM mitgeliefert wird. Es zeigt, wie man JDOM einsetzt, um Konfigurationsinformationen aus dem XML-Konfigurationsdokument in einer WAR-(Webarchiv-)Datei zu lesen. Achten Sie besonders in der Methode read() darauf, wie leicht es JDOM macht, spezifische Elemente aus dem DOM-Baum zu lesen, ohne dass man Code schreiben muss, um durch den Baum zu parsen. Zudem werden alle Elemente in Java-Standardsammlungen ausgegeben.
Wie bereits zuvor erwähnt, ist JDOM derzeit als Beta-Version verfügbar, was schon seit längerer Zeit der Fall ist. Die Autoren können sich anscheinend nicht entscheiden, wann die Merkmale von JDOM vollständig genug sind, um es tatsächlich auf den Markt zu bringen. Zum Stand dieses Artikels läuft es in Beta 7. Da XML einem derart raschen Wandel unterliegt, werden sie wohl nie eine Version auf den Markt bringen, wenn sie es mit den aktuellsten APIs immer auf dem neuesten Stand halten wollen. Sein Status hat jedoch nicht verhindert, dass es sowohl in Produktionsanwendungen als auch in Entwicklungswerkzeugen verwendet wird. Tatsächlich wird die aktuelle Version von JBuilder als eine der integrierten Bibliotheken mit JDOM mitgeliefert. So wird es sogar im Beta-Status bereits häufig verwendet. Unsere Firma hat es eingesetzt; man bewertete es dort als sehr stabil und seine Leistungsfähigkeit als relativ hoch.
Da JDOM noch als Beta-Version läuft, können Sie noch keine kompilierte Jar-Datei herunterladen. Wenn Sie jedoch den Quellcode herunterladen, ist ein Ant-Skript beigefügt, das die Jar-Datei und Beispiele für Sie aufbaut. Zur Zeit gibt es einige Konfigurationsfragen, auf die Sie achten sollten, insbesondere im Hinblick auf die Version des Xerces-Parsers, den Sie in Ihrem Klassenpfad installiert haben. JDOM verwendet Xerces intern, und es erwartet SAX- und DOM-Parser, die die Level-2-Version dieser APIs unterstützen. Wenn Sie eine ältere Xerces-Version in Ihrem Klassenpfad haben, kann dies zu Problemen führen. Hierzu gibt es jedoch eine einfache Arbeit, die in den Versionsmitteilungen für DOM beschrieben ist.
SOAP
SOAP steht für Simple Object Access Protocol. Es ist eine Methode mit offenem Standard zur Ausführung von Fernprozeduraufrufen, die ein textbasiertes Transportmittel (normalerweise HTTP) und XML verwendet. Es ist eine der Grundlagen von Web Services, was derzeit bei verteilten Rechnersystemen ein topaktuelles Thema ist. Doch warum ist SOAP so wichtig und warum sind alle so begeistert von dieser Art, Methodenaufrufe durchzuführen? Letztlich steht es für einen einfachen Weg, sprachenübergreifend ferngesteuerte Prozeduren aufzurufen. Das soll nicht heißen, dass dies lange Zeit nicht möglich gewesen wäre. Schließlich geht es bei COM, CORBA und RMI genau darum. Das Problem bei diesen Methodenaufrufverfahren liegt jedoch darin, dass es sich bei allen um binäre Standards handelt. Dies funktioniert einfach und effizient in lokalen Netzwerken, wird aber problematisch, wenn man es bei verteilten Rechnersystemen im Internet versucht. Fragen Sie doch mal, wie viele Netzwerkadministratoren binäre Ports an den Firewalls Ihrer Firma öffnen wollen! SOAP und Internetdienste sind attraktiv, da die meisten Netzwerke den freien Durchgang von Text bereits zulassen (normalerweise über den HTTP-Port). SOAP steht für eine sprachen- und plattformunabhängige Technik zur Ausführung von Methodenaufrufen, indem die Daten innerhalb von XML geordnet und dieses XML-Paket dann über HTTP transportiert wird.Ich möchte beschreiben, wie man die SOAP-Implementierung von Apache einsetzt. Es ist keine Einführung zu SOAP an sich (dies allein würde mindestens ein Buch füllen), doch ich werde SOAP gerade so ausführlich behandeln, dass die Beispiele verständlich werden. Beachten Sie, dass Sie SOAP ohne irgendeine Systemumgebung programmieren können - wenn Sie einen XML-Parser haben, können Sie mit SOAP arbeiten. Es ist jedoch immer angenehm, wenn schon ein anderer (wie Apache) den meisten Installationscode für Sie geschrieben hat. Das SOAP Toolkit von Apache ermöglicht es Ihnen, entweder SOAP-Dienste anzulegen oder Clients, die mit SOAP-Diensten kommunizieren. Wir werden beides besprechen. Doch zunächst müssen Sie das System installieren.
Installation
Die Installation von SOAP läuft ähnlich wie die Installation von anderen Apache-Produkten. Sie laden eine Zip-Datei herunter, die in ein Verzeichnis entpackt werden muss. Jetzt sind nur noch einige wenige Schritte zu tun, dann ist SOAP installiert und startbereit. Diese werden in der Dokumentation behandelt, die mit der SOAP-Implementierung von Apache geliefert wird; ich erwähne sie hier deshalb nur kurz. Es gibt separate Anweisungen für die Installationen der Client-Seite zur Server-Seite, doch der Server ist dem Client übergeordnet. Für den Client müssen Sie zuerst Folgendes besorgen:- den Klassenpfad aktualisieren, um die Datei soap.jar einzubinden
- mail.jar, von der Sun-Internetadresse (java.sun.com/products/javamail/)
- activation.jar, ein Bestandteil des JavaBeans Activation Framework (java.sun.com/products/beans/glasgow/jaf.html)
- einen beliebigen JAXP-kompatiblen XML-Parser (ich selbst habe Xerces 1.4.0 eingesetzt). Wenn Sie einen älteren Parser (der Namespaces nicht unterstützt) in Ihrem Klassenpfad haben, müssen Sie sicherstellen, dass der neuere Parser im Klassenpfad vor dem älteren erscheint.
Sobald Sie alle beweglichen Teile eingerichtet haben, sollten Sie Ihre Servlet-Maschine starten und auf den lokalen URL http://localhost:8080/soap/servlet/rpcrouter zugreifen können (natürlich können der Host-Name und Port in Ihrem Fall anders lauten - dieser gilt für TomCat). Es erscheint dann folgende Meldung:
Sorry, I don't speak via HTTP GET- you have to use HTTP POST to talk to me.
SOAP-Dienste
Ein SOAP-Dienst ist ein Software-Artefakt, das Abfragen empfängt und durch das Senden von SOAP-Meldungen antwortet, die normalerweise eine Nutzinformation enthalten. Das meiste SOAP-spezifische XML dient als Leitwegangaben und Metadaten für das Thema der Nachricht (oder Nutzlast). Sie können sich SOAP als einen Umschlag vorstellen, der das Dokument von irgendeinem Absender per Post zu Ihnen nach Hause trägt. SOAP ist eigentlich nur ein Codierungsmechanismus, der es Ihnen ermöglicht, Methoden, Parameter und Rückmeldungsarten anzugeben, die nicht an eine bestimmte Sprache gebunden sind.Wenn Sie einen Dienst anlegen, müssen Sie entscheiden, welche Dienste Sie anbieten wollen. Eines der Beispiele, die mit SOAP von Apache ausgeliefert werden, ist ein Adressbuchdienst. Er ermöglicht es Ihnen, eine Adresse zu einem Namen abzufragen, neue Adressen hinzuzufügen, das vorhandene Adressbuch anzuzeigen und Listen hinzuzufügen. Die Implementierung dieses Dienstes speichert die Adressen in Hashtable, doch für den Abnehmer des Dienstes spielt dies nicht die geringste Rolle. Dies ist jedoch einer der Punkte, bei dem man ein Transportmittel wie SOAP einsetzen kann. Die Art des Dialogs mit dem Dienst ist festgelegt, wobei die Einzelheiten der Implementierung dem Entwickler des Dienstes überlassen bleiben. Beim Adressbuch werden die Methoden, die aufgerufen werden können, während der Registrierung des Dienstes beim Apache SOAP-Router definiert.
Listing 5
public Address getAddressFromName(String name)throws IllegalArgumentException{if (name == null){throw new IllegalArgumentException("The name argument must not be null.");}return (Address)name2AddressTable.get(name);}
Sobald die Dienstklasse und ihre Hilfsklassen geschrieben sind, müssen Sie diese beim SOAP-Router registrieren. Wenn Sie dies erledigen, legen Sie eine Ressource an, die von einem Client aufgerufen werden kann, um Informationen auszugeben. Es gibt zwei Wege, einen Dienst beim Apache SOAP-Router zu registrieren. Der erste geht über den Admin-Client, der als Web-Anwendung läuft. Abpictureung 1 zeigt den Admin-Client in Betrieb, mit seinen drei Optionen.
Wenn Sie die Option Deploy auswählen, können Sie alle Detailangaben zu Ihrem Dienst in das in Abpictureung 2 dargestellte Formular eingeben.
Listing 7
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"id="urn:AddressFetcher"><isd:provider type="java"scope="Application"methods="getAddressFromName addEntry getAllListings putListings"><isd:java class="samples.addressbook.AddressBook" static="false"/></isd:provider><isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener><isd:mappings><isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"xmlns:x="urn:xml-soap-address-demo" qname="x:address"javaType="samples.addressbook.Address"java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/><isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"xmlns:x="urn:xml-soap-address-demo" qname="x:phone"javaType="samples.addressbook.PhoneNumber"java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/></isd:mappings></isd:service>
Der Client
Listing 8
package samples.addressbook;import java.io.*;import java.util.*;import java.net.*;import org.w3c.dom.*;import org.apache.soap.util.xml.*;import org.apache.soap.*;import org.apache.soap.encoding.*;import org.apache.soap.encoding.soapenc.*;import org.apache.soap.rpc.*;/*** See \samples\addressbook\readme for info.** @author Matthew J. Duftler (duftler@us.ibm.com)*/public class GetAddress{public static void main(String[] args) throws Exception{if (args.length != 2&& (args.length != 3 || !args[0].startsWith("-"))){System.err.println("Usage:");System.err.println(" java " + GetAddress.class.getName() +" [-encodingStyleURI] SOAP-router-URL nameToLookup");System.exit (1);}// Process the arguments.int offset = 3 - args.length;String encodingStyleURI = args.length == 3? args[0].substring(1): Constants.NS_URI_SOAP_ENC;URL url = new URL(args[1 - offset]);String nameToLookup = args[2 - offset];SOAPMappingRegistry smr = new SOAPMappingRegistry();BeanSerializer beanSer = new BeanSerializer();// Map the types.smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("urn:xml-soap-address-demo", "address"),Address.class, beanSer, beanSer);smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("urn:xml-soap-address-demo", "phone"),PhoneNumber.class, beanSer, beanSer);// Build the call.Call call = new Call();call.setSOAPMappingRegistry(smr);call.setTargetObjectURI("urn:AddressFetcher");call.setMethodName("getAddressFromName");call.setEncodingStyleURI(encodingStyleURI);Vector params = new Vector();params.addElement(new Parameter("nameToLookup", String.class,nameToLookup, null));call.setParams(params);// Invoke the call.Response resp;try{resp = call.invoke(url, "");}catch (SOAPException e){System.err.println("Caught SOAPException (" +e.getFaultCode() + "): " +e.getMessage());return;}// Check the response.if (!resp.generatedFault()){Parameter ret = resp.getReturnValue();Object value = ret.getValue();System.out.println(value != null ? "\n" + value : "I don't know.");}else{Fault fault = resp.getFault();System.err.println("Generated fault: ");System.out.println (" Fault Code = " + fault.getFaultCode());System.out.println (" Fault String = " + fault.getFaultString());}}}
// Map the types.smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("urn:xml-soap-address-demo", "address"),Address.class, beanSer, beanSer);smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("urn:xml-soap-address-demo", "phone"),PhoneNumber.class, beanSer, beanSer);
// Build the call.Call call = new Call();call.setSOAPMappingRegistry(smr);call.setTargetObjectURI("urn:AddressFetcher");call.setMethodName("getAddressFromName");call.setEncodingStyleURI(encodingStyleURI);Vector params = new Vector();params.addElement(new Parameter("nameToLookup", String.class,nameToLookup, null));call.setParams(params);
Listing 9
// Invoke the call.Response resp;try{resp = call.invoke(url, "");}catch (SOAPException e){System.err.println("Caught SOAPException (" +e.getFaultCode() + "): " +e.getMessage());return;}// Check the response.if (!resp.generatedFault()){Parameter ret = resp.getReturnValue();Object value = ret.getValue();System.out.println(value != null ? "\n" + value : "I don't know.");}else{Fault fault = resp.getFault();System.err.println("Generated fault: ");System.out.println (" Fault Code = " + fault.getFaultCode());System.out.println (" Fault String = " + fault.getFaultString());}
In diesem Beispiel werden die Fähigkeiten des SOAP Toolkits nur oberflächlich behandelt. Es gibt auch Klassen, die es Ihnen ermöglichen, auf eine niedrigere Abstraktionsebene zu gelangen und direkt mit den SOAP-Headern und dem Envelope zu arbeiten. Wie Sie sehen, gibt es zahlreiche Hilfemethoden, um das Arbeiten mit SOAP zu erleichtern.
Webdienste
Wenn Sie nicht gerade in einer Höhle gelebt haben, haben Sie sicher den ganzen Medienrummel um die Web Services mitbekommen. Eine der Technologien, die den Webdiensten zugrunde liegt, ist SOAP: Es wird verwendet, um die Methodenaufrufe auszuführen. Web Services werden von einigen weiteren, SOAP-externen Standards unterstützt, die über das Thema dieses Artikels hinausgehen. Zum Beispiel verwendeten wir ein proprietäres XML-Dokument oder ein Webformular, um unseren Dienst beim Apache-Server zu registrieren. Um Aufrufe bei unserem Dienst zu tätigen, mussten wir vorab wissen, welche Methoden zur Verfügung stehen und wie sie aufgerufen werden können. Web Services definiert Leistungsmerkmale wie z. B. WSDL (Web Services Definition Language), bei dem es sich um ein Verzeichnis handelt, das die Eigenschaften eines Webdienstes definiert und wie er aufgerufen wird. Sicher können Sie das Apache SOAP-System verwenden, um Webdienste anzulegen und mit anderen Webdiensten zu kommunizieren. Es muss jedoch außer SOAP noch weitere Infrastruktur eingerichtet sein.Zusammenfassung
Im zweiten Teil unseres Java-XML-Workshops haben wir Sie in die Open Source API JDOM sowie in die SOAP-Implementierung von Apache eingeführt. JDOM ist für das interaktive Arbeiten mit XML eine großartige Möglichkeit, wenn Sie Java-Entwickler im engeren Sinne sind oder schnell etwas programmieren müssen. Wenn Sie Code in anderen Sprachen schreiben, sind Sie wahrscheinlich gut bedient, wenn Sie die DOM-APIs erlernen und sie überall einsetzen (was Ihre Lernkurve verkürzt).Wenn Sie nur XML-Code in Java schreiben, ist JDOM eine bequeme Alternative zu den notwendigerweise komplexen SAX- und DOM-APIs.Wenn Sie einen XML-Parser besitzen, können Sie direkt mit SOAP arbeiten. Jedoch überlässt man die Details auf der niederen Ebene am besten anderen Entwicklern. Das SOAP Toolkit ist ein elegant konstruiertes System für das Arbeiten mit SOAP, für Server, die entweder in Java oder einer anderen SOAP-fähigen Sprache geschrieben sind.
Neal Ford ist Vice President Technology bei der in Atlanta ansässigen DSW Group. Er hat zu den Themen Java und Delphi veröffentlicht und spricht regelmäßig auf internationalen Konferenzen, so auch der JAX2002 oder der Entwickler Konferenz.




