Grundsatz der neuen Achse

Apache Axis2: AXIOM – das neue Objektmodell für XML-Verarbeitung
Kommentare

Da fast alle Web-Service-Nachrichten in XML oder XML-ähnlichen Formaten vorliegen, ist es eminent wichtig, einen effizienten und leistungsfähigen Mechanismus für die XML-Verarbeitung einzusetzen. Als Web-Service-Engine der nächsten Generation hat Axis2 die Herausforderung angenommen, die Performance von Axis1 noch einmal zu verbessern. Die Antwort auf diese Herausforderung heißt AXIOM – ein Objektmodell, welches Performanz und Benutzerkomfort in sich vereint.

AXIOM basiert auf dem neuen Pull-Parsing-Mechanismus, der unter dem JSR 173 – Streaming API for XML (StAX)  – definiert ist. Bis jetzt sind die meisten ereignisbasierten Parser sog. Push Parser. Solche Parser füttern die Anwendung immer mit allen Daten aus dem XML-Infoset und berücksichtigen nicht, ob die Applikation noch an weiteren Daten interessiert ist. Es ist für die Applikation nicht möglich, den Parser anzuhalten oder abzubrechen. Für den Anwendungsfall, dass ein SOAP Intermediary nur ein bestimmtes Element aus SOAP:Header auslesen möchte und sich für den umfangreicheren SOAP:Body gar nicht interessiert, ist die Verwendung eines Push Parser daher nicht geeignet, da der Parser das komplette Dokument durchscannt und alle Ereignisse an die Applikation meldet.

Beim Pull Streaming Model spielt die Applikation die aktive Rolle und behält die Kontrolle über den Verarbeitungsprozess. Nur nach Aufforderung der Applikation liefert der Parser das nächste Ereignis zurück. Die Applikation kann jederzeit darüber entscheiden, ob die Verarbeitung angehalten, fortgesetzt oder abgebrochen werden soll. Die Rollenverteilung zwischen Parser und Anwendung wird im Vergleich zum Push Parser vertauscht, sodass die Applikation flexibel den Verarbeitungsprozess je nach Situation beeinflussen kann.

Im Gegensatz zu SAX, das nur das Lesen von XML-Infosets unterstützt, ermöglicht das StAX API auch das Erstellen und Modifizieren von XML-Infosets. Darüber hinaus bietet ein Pull Parser auch eine Filterungsfunktion, welche bestimmte Ereignistypen von Anfang an ausschließt und damit die Verarbeitungseffizienz steigert. Durch die Standardisierung in Form des JSR 173 haben Pull Parser große Aufmerksamkeit erweckt. Mittlerweile existieren schon mehrere Implementierungen.

Den Einstiegspunkt zu StAX bildet analog zu anderen APIs in JAXP eine Factory, die in diesem Fall XMLInputFactoryheißt. Nachdem eine Instanz von XMLInputFactory erzeugt ist, kann ein XMLStreamReader über die Factory angelegt und damit ein XML-Infoset geparst werden. XMLStreamReader ist das wichtigste Interface im Cursor API und kapselt sämtliche Methoden für die Zugriffe auf das XML-Infoset. Mit der Methode hasNext() kann geprüft werden, ob noch weitere Daten im Strom verfügbar sind. Falls ja, wird die next()-Methode aufgerufen, welche einen Integerwert zurückliefert, der Auskunft über den Typ des aktuellen Ereignisses gibt. Alle Ereignistypen sind als Konstanten in dem Interface XMLStreamConstants definiert. Je nach Ereignistyp kann eine Submenge der Methoden der Klasse XMLStreamReader aufgerufen werden, um dann typspezifische Daten abzufragen. Aufrufe bestimmter Methoden für falsche Ereignistypen führen entweder zu sinnlosen Werten oder Fehlern. Diese Kontextsensitivität bringt natürlich eine hohe Fehleranfälligkeit mit sich, was jedem Entwickler klar sein soll. Programmcode, der mit dem Cursor API ein XML-Infoset verarbeitet, besteht typischerweise aus einer Schleife, in der die Ereignisse nacheinander abgefragt und verarbeitet werden. In Listing 1 wird eine Java-Klasse gezeigt, welche mit StAX ein XML-Dokument einliest.

Aufgrund seiner hervorragenden Eigenschaften bzgl. Performance, Ressourcenverbrauch und Kontrollierbarkeit wird StAX z.B. für die Verarbeitung von großen Dokumenten in absehbarer Zeit SAX den Rang ablaufen und zum wichtigsten Streaming API aufsteigen. Ein weiterer interessanter Punkt von StAX ist, dass es eine dritte Darstellungsform von XML-Infoset ermöglicht. Bis jetzt liegt ein XML-Infoset entweder als Datenstrom (SAX) oder als ein baumartiges Objektmodell (DOM oder JDOM) vor. Durch die XMLEvent-Klassenhierarchie im StAX API kann ein XML-Infoset ebenfalls als eine Liste von XMLEvent-Objekten repräsentiert werden. Diese Objekte können dann später beliebig oft für verschiedene Zwecke wieder herangezogen werden, um die Verarbeitung fortzusetzen oder ein neues Objektmodell aufzubauen. Alle dieser Eigenschaften haben dazu geführt, dass AXIOM StAX als grundlegenden Verarbeitungsmechanismus ausgewählt hat.

AXIOM-Architektur

Ein baumbasiertes API mit seinem vorhandenen Objektmodell, wie z.B. DOM, wird von den meisten Entwicklern aufgrund des geringeren Entwicklungsaufwands bevorzugt. Dabei werden der damit verbundene Performanceverlust sowie der Speicherverbrauch teilweise auch bewusst in Kauf genommen. Obwohl StAX im Vergleich mit anderen Streaming APIs eine wesentliche Verbesserung bzgl. Performance und Kontrollierbarkeit bietet, handelt es sich nach wie vor um ein Streaming API. Das bedeutet, dass die Applikation selbst den Inhalt aus dem Infoset verwalten muss. Ein freies Navigieren sowohl vorwärts als auch rückwärts in einer Baumstruktur wie bei einem baumbasierten API ist nicht ohne weiteres möglich.

Vor diesem Hintergrund haben die Entwickler von Axis2 schon früh damit angefangen, ein neues und effizientes Objektmodell zu etablieren, was die Vorteile der beiden Welten (gute Performance und niedriger Ressourcenverbrauch von Streaming APIs sowie komfortable Zugriffsmöglichkeit von baumbasierten APIs) in sich vereint. Das dabei entstandene Objektmodell wurde AXIOM (Axis Object Model) getauft. Aufgrund der universellen Einsetzbarkeit von AXIOM ist es mittlerweile aus dem Axis2-Projekt herausgelöst und als eines der ersten Module in das WS-Commons-Projekt aufgenommen worden. Wesentliche Features von AXIOM sind:

  • Leichtgewichtigkeit: Beim Design von AXIOM wurde stets darauf geachtet, dass das API einfach und leichtgewichtig gestaltet ist. Dieses Ziel wird unter anderem dadurch erreicht, dass die Tiefe der Klassenhierarchie sowie die Anzahl von Methoden und Attributen der Klassen möglichst gering gehalten wurden.
  • XML-Infoset-konform: Das XML-Infoset wird vollständig unterstützt.
  • Aufgeschobener oder verzögerter Aufbau (Engl.: deferred building): Dies ist das wichtigste Feature von AXIOM und bedeutet grob, dass das Objektmodell nur auf Anforderung aufgebaut wird.
  • StAX-basiert: AXIOM basiert auf StAX. Um jedoch bestehende XML-Werkzeuge, die meistens das ältere SAX API benutzen, zu unterstützen, enthält AXIOM auch einen SAX-Adapter.
  • SOAP-Optimierung: Basierend auf dem Objektmodell, das allgemeine XML-Infosets abbildet, wird eine zusätzliche Schicht angeboten, die SOAP-spezifische Modellklassen enthält.
  • XOP/MTOM: AXIOM unterstützt auch binäre Daten im XML-Infoset. Dies bildet eine wichtige Grundlage für MTOM-Realisierung in Axis2.
  • XPath: AXIOM bietet seit neuestem auch Unterstützung für XPath an. Als XPath Engine wird JAXEN verwendet.

Das wichtigste Interface in AXIOM ist Builder, das für den Aufbau des Objektmodells zuständig ist. Intern kapselt ein Builder einen XMLStreamReader oder einen XMLStreamWriter, um XML-Infoset zu verarbeiten oder zu erstellen.

Abb. 1. Builder Interface kapselt Zugriffe auf das StAX API
  • OM Builder (StAXOMBuilder.java): Dieser Builder kann das Objektmodell eines allgemeinen XML-Infosets konstruieren.
  • SAOP Builder (StAXSOAPModelBuilder.java): Dieser Builder ist für die Verarbeitung von SOAP-Nachrichten optimiert und baut intern ein SOAP-spezifisches Objektmodell mit Elementen wie SOAPEnvelope,SOAPHeader und SOAPBody usw. auf.
  • MTOM Builder (MTOMStAXSOAPModelBuilder.java): ist eine Unterklasse des SOAP Builder und unterstützt binäre Attachments in einem XML-Infoset nach dem MTOM-Standard.
  • SAX Builder (SAXOMBuilder.java): Da SAX nach wie vor ein sehr verbreitetes XML Parsing API ist, stellt AXIOM ebenfalls einen SAX Builder zur Verfügung, der ein Objektmodell aus SAX-Ereignissen bauen kann.

Um das interne Objektmodell zu verwalten, wurden verschiedene Speichermodelle implementiert. Das voreingestellte Modell basiert auf einer verketteten Liste. Ein zweites Speichermodell basiert auf dem W3C DOM API, sodass man eine DOM-konforme Implementierung mit AXIOM-Funktionalität zur Verfügung hat. Durch das flexible API von AXIOM kann auch ein benutzerdefiniertes Speichermodell implementiert und aktiviert werden. Mithilfe vonOMFactory wird das zu benutzende Speichermodell über Property ausgewählt und ausgetauscht.

Der wesentliche Unterschied zwischen AXIOM und anderen Objektmodellen besteht darin, dass der Aufbau von Objektmodellen in AXIOM aufgeschoben wird. Diese Feature wird in der AXIOM-Terminologie als „Deferred Building“ bezeichnet. Der Objektmodellaufbau erfolgt nur dann, wenn es für die Applikation absolut notwendig ist. Die genaue Funktionsweise von Deferred Building wird nun anhand eines Beispiels erklärt.

Listing 1: Beispiel-XML-Dokument (AXIOMsample.xml)
-------------------------------------------------------------------------
Axis HotelDuke Apache
Spring Street4288888JavaDreamland

Wenn nur der Name des Managers vom Hotel aus Listing 1 gewünscht ist, liest AXIOM den Datenstrom nur bis , und auch nur das XML-Segment, das bis dahin gelesen wurde, wird als Objektmodell im Speicher aufgebaut, während der Rest des Dokuments nach wie vor im Datenstrom gehalten wird. Diese Technik ist besonders wichtig bei der Verarbeitung großer XML-Infosets oder Weiterleitung von Infosets durch eine SOAP Intermediary, die nur ein partielles Segment (SOAP Header) des gesamten Infosets einliest. Durch die Nutzung des StAX Parser kann der AXIOM Builder so lange vom StAX Parser bzw. XMLStreamReader Ereignisse anfordern, bis das Element komplett eingelesen ist. Das Objektmodell wird dabei aufgebaut, sodass der Benutzer über das AXIOM API komfortabel auf den Textinhalt des Elements zugreifen kann. Sollte der Benutzer später auch die Stadt ermitteln, in der das Hotel liegt, wird der AXIOM Builder den XMLStreamReader zum Fortschreiten veranlassen. Alle dabei vom XMLStreamReader gelieferten Ereignisse können vom AXIOM Builder zum Aufbau des Objektmodells benutzt werden. Alle diese Schritte sind für den Benutzer transparent.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -