Axis2 versus XFire – Das Duell
Kommentare

Data Bindings
Axis 1.x lieferte ein eigenes Type-Mapping-Framework, mit dem die Umwandlung der XML-basierten SOAP-Nachrichten in Java-Typen erfolgte und umgekehrt. Die neue Web-Service-Spezifikation

Data Bindings

Axis 1.x lieferte ein eigenes Type-Mapping-Framework, mit dem die Umwandlung der XML-basierten SOAP-Nachrichten in Java-Typen erfolgte und umgekehrt. Die neue Web-Service-Spezifikation JAX-WS delegiert solche Serialisierungsarbeiten nun an JAXB2. Im Open-Source-Bereich haben sich darüber hinaus einige weitere Projekte etabliert, die sich ebenso mit der Serialisierung von XML nach Java und umgekehrt beschäftigen: XML­Beans, JiBX, JaxMe und einige andere mehr. Jedes der genannten Projekte hat seine Besonderheiten, ein großer Vorteil von neuen SOAP-Frameworks wie XFire oder Axis2 liegt nun in der Tatsache, dass der Entwickler jetzt sehr einfach unterschiedliche Data Bindings einsetzen kann. XFire und Axis2 ermöglichen die Verwendung von XMLBeans, JibX und JAXB 1.1. XFire verfügt, bedingt durch seinen JAX-WS-Support, zusätzlich schon über Unterstützung von JAXB 2.0. Axis2 kann hier nur JaxMe anbieten, welches eine Open-­Source-­Implementierung von JAXB 1.1 ist. Darüber hinaus gibt es in Axis2 mit ADB ein weiteres, eigenes Data-Binding-Framework, welches auch per Default verwendet wird.

Bedenken sollte man bei all den Möglichkeiten jedoch, dass man nur dann die freie Auswahl an Data-Binding-Frame­works hat, wenn man Web Services schreibt, die nicht konform mit JAX-WS sind. Andernfalls ist man gezwungen, JAXB2 zu verwenden.

Von StAX zu AXIOM

Beide Projekte benutzen intern StAX für die Verarbeitung von SOAP-Nachrichten. Bei Axis2 setzt man jedoch nicht direkt auf StAX auf, sondern man hat noch eine zusätzliche Schicht eingezogen: AXIOM.

AXIOM steht für AXIs Object Model, setzt auf StAX auf und bietet ein ähnlich einfaches Programmiermodell wie DOM zum Zugriff auf XML-Daten. Unter Verwendung von AXIOM werden Objekte erst erzeugt, wenn Sie wirklich benötigt werden, der Rest verbleibt im Stream. Sehr einfach gestaltet sich auch das Navigieren durch ein XML-Dokument. Mit AXIOM können damit sehr große SOAP-Nachrichten schnell, speichersparend und leicht verarbeitet werden. Axis2 basiert auf ­AXIOM. Benutzer von Axis2 werden früher oder später mit AXIOM Bekanntschaft schließen (müssen), denn in Axis2 werden Parameter und Rückgabewerte von Services nämlich nicht direkt in Java-Datentypen konvertiert, sondern immer in einem AXIOM-Objekt-Wrapper gehalten. Dies ist ein großer Unterschied zu XFire. Jetzt könnte fast der Eindruck entstehen, dass man mit Axis2 eventuell nicht so ohne weiteres in der Lage sein könnte, beispielsweise ein POJO als Web Service zu veröffentlichen. Selbstverständlich gibt es auch hier, z.B. unter Verwendung des so genannten RPCMessageReceiver, Wege, um AXIOM größtenteils zu umgehen. AXIOM ist dennoch sicherlich eine Bereicherung für Axis2, denn dank seiner bietet sich in Axis2 neben den gleichen Möglichkeiten wie Axis 1.x und XFire zusätzlich die wertvolle Op­tion, direkt auf XML-Ebene zu operieren. Hier soll außerdem nicht unerwähnt bleiben, dass AXIOM mittlerweile ein eigenes Apache-Projekt geworden ist, welches man separat beziehen und auch außerhalb von Axis2 für die Verarbeitung von XML verwenden kann. 

Deployment und Administration von Web Services

Für die Entwicklung von Web Services gibt es zwei Methoden: Code First und Contract First. Diese beiden Verfahren konnte man bereits mit Axis 1.x verwenden und sie stehen natürlich auch bei XFire und Axis2 weiterhin zur Verfügung.

Es fällt auf, dass Axis2 an vielen Stellen einfacher und bequemer zu verwenden ist als sein Gegenpart. Ein gutes Beispiel hierfür ist das Deployment von Web Services. Wenn man mit XFire einen Web Service über HTTP veröffentlichen will, dann erstellt man üblicherweise eine komplette Webanwendung (.war), welche die Web-Service-Implementierung selbst und auch die XFire-Distribution (oder einen Teil davon) enthält. Durch Einspielen dieser Webanwendung in einen Servlet-Container steht der Web Service zur Verfügung.

Anders bei Axis2: Hier gibt es mit der separat zu beziehenden Axis2-Webanwendung eine Axis2-Distribution, die man in den Servlet-Container einspielt. Diese Axis2-Webanwendung bietet eine Administrationsoberfläche, mit der man über einen Upload-Mechanismus jetzt beliebig viele Archive (mit der Dateiendung .aar), die ausschließlich den Web-Service-Code enthalten, installieren und verwalten kann. Axis2 installiert den Web Service nach dem Upload in sein Repository und anschließend steht er zur Verfügung. Abbildung 1 zeigt die Dateistruktur für einen Web Service, wie er mit XFire veröffentlicht würde.

Abb. 1: Die Dateistruktur für den XFire Web Service (Webapplikation; .war)

Es handelt sich um ein normales Webarchiv (.war). Im lib-Verzeichnis müssen die XFire-Bibliotheken samt Abhängigkeiten enthalten sein. Wichtig ist hier auch die web.xml, in der das Mapping zum XFire­Servlet konfiguriert ist und in der man festlegen kann, wo services.xml liegt. Bei dieser Konfigurationsdatei handelt es sich um das Gegenstück zur ­WSDD aus Axis 1.x kennt. Hier wird der Web Service selbst konfiguriert. Im Normalfall wird die Datei services.xml im Verzeichnis classes/META-INF/x-fire erwartet.

Abbildung 2 zeigt den gleichen Service, wie er in Axis2 deployt würde: Es werden lediglich die Implementierungsklassen gezippt, und im Verzeichnis META-INF wird ebenfalls eine Datei services.xml mitgegeben; auch hier ist diese Datei für die Konfiguration des Web Service zuständig.

Abb. 2: Die Dateistruktur für den Axis2 Web Service (Axis Archive; .aar)
Einen POJO Web Service entwickeln

Zum Abschluss sollen die Unterschiede direkt anhand eines einfachen Code-First-basierenden Beispiels erforscht werden. Zunächst sollte man sich die jeweils neuesten Versionen von XFire und Axis2 (Standard-Distribution und Webapplikation) besorgen. Das axis2.war ist in einen beliebigen Servlet-Container zu deployen, und die beiden ZIP-Dateien mit XFire und Axis2 werden einfach entpackt (zum Beispiel direkt auf C:).

Nun soll eine leicht erweiterte Version des BookService-Beispiels, das man bei XFire findet, entstehen, und dieses soll nun sowohl für XFire als auch für Axis2 umgesetzt werden. Als Erstes sollte man in Eclipse ein neues Java-Projekt mit dem Namen BookService anlegen (bitte darauf achten, dass separate Ordner für Source­ und Output ausgewählt wurden). Da dieses Projekt sowohl für das Axis2- als auch für das XFire-Deployment verwendet werden soll, sind nun zwei Ordner in der Projektstruktur anzulegen: Axis2Config und XFireConfig. Hier werden später die frameworkspezifischen Deployment-Deskriptoren (services.xml) abgelegt. Die Implementierung des Web Service beginnt mit dem Anlegen einer Book-Klasse. Ein Buch-Objekt kann mehrere Autoren haben, daher benötigt man außerdem eine Author-Klasse (Listings 1 und 2).

Listing 1: Das Book-Objekt wird vom Web Service zurückgegeben
-----------------------------------------------------------------------------
package de.javamagazin;

public class Book {

     private String title;
     private String isbn;
     private Author[] authors;

     public Book() {
     }

     public Book(String title, String isbn, Author[] authors) {
          this.title = title;
          this.isbn = isbn;
          this.authors = authors;
     }

     public String getIsbn() {
          return isbn;
     }

     public void setIsbn(String isbn) {
          this.isbn = isbn;
     }

     public String getTitle() {
          return title;
     }

     public void setTitle(String title) {
          this.title = title;
     }

     public Author[] getAuthors() {
          return authors;
     }

     public void setAuthors(Author[] authors) {
          this.authors = authors;
     }

}
Listing 2: Jedes Buch kann mehrere Autoren haben
---------------------------------------------------------------------------
package de.javamagazin;

public class Author {

     private String name;
     private String firstName;
     private int yearOfBirth;

     public Author() {
     }

     public Author(String name, String firstName, int yearOfBirth) {
          this.name = name;
          this.firstName = firstName;
          this.yearOfBirth = yearOfBirth;
     }

     public String getFirstName() {
          return firstName;
     }

     public void setFirstName(String firstName) {
          this.firstName = firstName;
     }

     public String getName() {
          return name;
     }

     public void setName(String name) {
          this.name = name;
     }

     public int getYearOfBirth() {
          return yearOfBirth;
     }

     public void setYearOfBirth(int yearOfBirth) {
          this.yearOfBirth = yearOfBirth;
     }

}
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -