Web Services mit Spring WS und JAXB - JAXenter
Enterprise Web Services mit Spring WS

Web Services mit Spring WS und JAXB

Thorsten Kamann

In Teil 1 dieser dreiteiligen Artikelserie haben wir gemeinsam einen Web Service auf Basis von Spring WS entwickelt. Dabei haben wir allerdings viel mit XML und dem SOAP-Body arbeiten müssen. In diesem Teil werden wir den Service verbessern, sodass wir JAXB verwenden und mit Objekten arbeiten können.

Im ersten Teil haben wir die Basisfunktionalitäten von Spring WS
[1] kennen gelernt. Wir haben den AbstractJDomPayloadEndpoint verwendet, um an die Daten zu gelangen, die der Request enthielt. Das ist eine sehr direkte Art der Datenverarbeitung und erinnert ein wenig an die Verwendung von JDBC, um mit Datenbanken und den SQL-Abfragen zu arbeiten. In diesem Teil wollen wir auf diese direkte Art der Datenverarbeitung verzichten und nur mit Objekten arbeiten. Dazu verwenden wir die Java Architecture for XML Binding (JAXB)
[3].

JAXB

JAXB ist ein XML-Binding-Framework, mit dem sich aus einer XML-Schema-Instanz die benötigten Java-Klassen generieren lassen. Somit können Sie mit XML-Dokumenten arbeiten, die auf diesem Schema basieren, ohne weitere Frameworks wie SAX nutzen zu müssen. Ein Schema haben wir bereits im ersten Teil erstellt. In diesem Schema beschreiben wir die drei Domänenobjekte Category, Supplier, DateRange und die Struktur des Requests, den wir erwarten (Abb. 1).

Abb. 1: XML Schema aus Teil 1

Da wir jetzt nicht nur den Request, sondern auch den Response über Objekte handeln wollen, müssen wir den Response noch dem Schema hinzufügen. Dieser Response kann eine beliebige Anzahl von gefundenen Produkten enthalten. Die Definition eines Produkts ist als anonymes Element realisiert (Abb. 2, Listing 1).

Abb. 2: Zusätzliches Element in dem XML Schema
Listing 1

    .

  
    
.

Anhand dieses Schemas kann JAXB alle benötigten Java-Klassen generieren. Um das zu bewerkstelligen, haben Sie mehrere Möglichkeiten. Sie können die mitgelieferten Tools von JAXB oder als Alternative Maven [4] verwenden. Für Maven gibt es ein Plug-in [5], das diese Aufgabe erledigt. Sie müssen in der pom.xml nur das Plug-in konfigurieren und an die richtige Lifecycle-Phase binden (Listing 2).

Listing 2
org.jvnet.jaxb2.maven2maven-jaxb2-plugintrue-Xfluent-apisrc/main/resources/META-INF/schemanet.java.dev.jaxb2-commonsjaxb-fluent-api2.1.8generate

Dieses Plug-in ist jedoch nur im JAVA.net Repository verfügbar. Wenn Sie keinen Repository-Manager wie Nexus [6] oder Artifacory [7] verwenden und in Ihrer settings.xml dieses Repository noch nicht konfiguriert haben, dann müssen Sie das in der pom.xml machen. Fügen Sie das Repository wie in Listing 3 einfach hinzu.

Listing 3
maven2-repository.dev.java.netJava.net Maven 2 Repositoryhttp://download.java.net/maven/2truefalsemaven2-repository.dev.java.netJava.net Maven 2 Repositoryhttp://download.java.net/maven/2

Wenn Sie nun Maven mit mvn generate-sources aufrufen, werden alle Java-Klassen generiert. Das Zielverzeichnis ist target/generated-sources/xjc. Eine Besonderheit hat diese Konfiguration des JAXB2-Plug-ins. Der XJC-Generator, der für die Erzeugung der Klassen verantwortlich ist, ist ebenfalls mit Plug-ins erweiterbar. Das nutzen wir und haben das Plug-in für die Erzeugung von Fluent-Interfaces-ähnlichem Code aktiviert. Dadurch können sie sehr schnell die Klassen verwenden und konfigurieren: new SupplierType().withId(123).withName(„SupplierName“);.

Abb. 3: Modell der mit XJC-generierten Klassen

In Abbildung 3 sehen Sie ein Modell der generierten Klassen. Wenn Sie dieses Modell mit dem XML Schema vergleichen, sehen Sie, dass die Klassen eins zu eins auf das Schema gemappt werden können. Das Verzeichnis, das die generierten Klassen enthält, müssen Sie Ihrem Projekt-BuildPath in Eclipse hinzufügen. Dadurch dass sich dieses Verzeichnis unterhalb von targetbefindet, wird man auch daran gehindert, diese Klassen in ein Versionierungssystem einzuchecken (Kasten: „Sollen die generierten Dateien in ein Versionierungssystem eingecheckt werden“).

Sollen die generierten Dateien in ein Versionierungssystem eingecheckt werden?

Da unter Umständen generierte Dateien potenziell durch jeden Build-Lauf neu erzeugt werden können, ohne sich inhaltlich zu ändern, wären das unnötige Check-ins. Dazu kommt, dass das XML Schema und die generierten Klassen direkt miteinander verknüpft sind. Man müsste also immer gleichzeitig beides einchecken. Diese potenzielle Fehlerquelle ist damit ausgeschlossen, da nur das Schema im Versionierungssystem vorhanden ist.

Geschrieben von
Thorsten Kamann
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.