XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen...

18
XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei als Datenquelle für den AutoKauf Web Service. Wenn der Web Service z. B. auf die Anfrage alleAutosAnzeigen die Liste AutoArrayItems (also ein Array) an den SOAP-Client zurückgibt, müssen die Daten (also die Arrayeinträge) ja irgendwo herkommen. Im Normalfall wird das eine SQL- Datenbank sein, aus der die Daten zur Laufzeit geholt werden. Im Fall unseres Praktikums ist es einfachheitshalber eine XML-Datei, die zur Laufzeit vom Web Service eingelesen (geparst), ggf. geändert und wieder gespeichert wird. Das Tutorial schließt an das Tutorial Java-basierten Web Service erstellen an. Inhaltsverzeichnis 1 IMPORTIEREN DES WEB SERVICE AUTOKAUF _____________ 1 2 XML-DATENBASIS _____________________________________ 2 2.1 XML Schema erstellen _________________________________________ 2 2.2 XML-Datei erstellen ___________________________________________ 4 2.3 XML-Datei und Schema in Eclipse-Projekt integrieren_______________ 6 3 WEB-SERVICE KLASSE AUTOKAUFSOAPBINDINGIMPL _____ 7 3.1 Methode alleAutosAnzeigen ____________________________________ 7 3.2 Methoden kaufeAuto und verkaufeAuto __________________________ 8 3.3 Methode generiereXMLDateipfad ________________________________ 9 3.4 Methode leseDatensaetze _____________________________________ 10 3.5 Methode schreibeDatensaetze _________________________________ 12 3.6 Testen des XML-Dateizugriffs __________________________________ 14 4 ERSTELLEN DES ARCHIVS AKWS1011GXX.WAR __________ 16

Transcript of XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen...

Page 1: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

XML-Datei für Web Service auslesen und schreiben

Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei als Datenquelle für den

AutoKauf Web Service. Wenn der Web Service z. B. auf die Anfrage alleAutosAnzeigen

die Liste AutoArrayItems (also ein Array) an den SOAP-Client zurückgibt, müssen die

Daten (also die Arrayeinträge) ja irgendwo herkommen. Im Normalfall wird das eine SQL-

Datenbank sein, aus der die Daten zur Laufzeit geholt werden. Im Fall unseres Praktikums ist

es einfachheitshalber eine XML-Datei, die zur Laufzeit vom Web Service eingelesen

(geparst), ggf. geändert und wieder gespeichert wird.

Das Tutorial schließt an das Tutorial Java-basierten Web Service erstellen an.

Inhaltsverzeichnis

1 IMPORTIEREN DES WEB SERVICE AUTOKAUF _____________ 1

2 XML-DATENBASIS _____________________________________ 2

2.1 XML Schema erstellen _________________________________________ 2

2.2 XML-Datei erstellen ___________________________________________ 4

2.3 XML-Datei und Schema in Eclipse-Projekt integrieren _______________ 6

3 WEB-SERVICE KLASSE AUTOKAUFSOAPBINDINGIMPL _____ 7

3.1 Methode alleAutosAnzeigen ____________________________________ 7

3.2 Methoden kaufeAuto und verkaufeAuto __________________________ 8

3.3 Methode generiereXMLDateipfad ________________________________ 9

3.4 Methode leseDatensaetze _____________________________________ 10

3.5 Methode schreibeDatensaetze _________________________________ 12

3.6 Testen des XML-Dateizugriffs __________________________________ 14

4 ERSTELLEN DES ARCHIVS AKWS1011GXX.WAR __________ 16

Page 2: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

1

1 Importieren des Web Service AutoKauf Die Vorrausetzung für dieses Tutorial ist, dass der Web Service AutoKauf schon

implementiert ist.

Um den Web Service in die Testumgebung zu integrieren, importieren wir das Archiv in

Eclipse als Projekt. Dies geschieht mit File -> Import -> Web -> WAR file.

Mit Rechtsklick auf das importierte Projekt AKWS1011GXX Run As -> Run on Server wird

dem Server der Web-Kontext hinzugefügt.

Page 3: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

2

Der Service ist also immer verfügbar, wenn das Tomcat-Plugin gestartet ist.

Mit der folgenden URL kann getestet werden, ob der Service aktiv ist.

http://localhost/AKWS1011GXX/services/AutoKauf

2 XML-Datenbasis Bei der Beispiel-Implementierung des Web Service Tutorials wären Änderungen an den

Daten innerhalb der Klasse AutoKaufImpl, hervorgerufen durch einen Webservice Aufruf,

nur temporär und bei der nächsten Anfrage wieder vergessen. Wir müssen diese Änderungen

also auf einer für alle Web Service Nutzer einheitlichen Datenbasis persistent schrieben. Dazu

verwenden wir eine XML-Datei. Diese XML-Datei kann beliebig viele Einträge von Autos

haben.

2.1 XML Schema erstellen

Das XML Schema ist eine Art Bildungsvorschrift für die XML-Datei. Um später bei der

Erstellung der XML-Datei auf Fehler hingewiesen zu werden (unter Verwendung

entsprechender XML-Editoren wie XMLSpy), werden XML-Dateien mit einem Schema

verknüpft und bei Änderungen gegen das Schema validiert.

Mit dieser Technik wird verhindert, dass in der späteren Implementation der Clients

unerklärliche Seiteneffekte aufgrund einer fehlerhaften XML-Datei auftreten.

Bevor wir bei der Frage wie solch ein XML Schema aussehen soll ins Schwitzen geraten,

schauen wir uns schnell noch einmal die im Tutorial Java-basierten Web Service erstellen

erstellte WSDL-Datei AKWS1011GXX.wsdl an und zwar speziell den Abschnitt Types. Da

steht nämlich schon fast alles drin was wir brauchen.

Page 4: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

3

Um ein korrektes XML Schema zu erhalten, mit dem wir XML-Dokument-Instanzen erstellen

können, müssen wir nur wenig ändern.

- den types-Tag löschen

- überflüssige Namespaces löschen

- das Root-Element AutoArrayItems definieren

Das Root-Element umschließt den gesamten Inhalt einer XML-Datei. In einer wohlgeformten

XML-Datei gibt es nur ein Root-Element.

<?xml version="1.0" encoding="UTF-8"?>

<types>

<xsd:schema … >

<xsd:complexType name="AutoArray">

<xsd:sequence>

<xsd:element name="AutoArrayItem" type="typesns:Auto" minOccurs="1" … />

</xsd:sequence>

</xsd:complexType>

<xsd:complexType name="Auto">

<xsd:sequence>

<xsd:element name="autoID" type="xsd:long"/>

<xsd:element name="farbe" type="xsd:string"/>

<xsd:element name="anzahlSitze" type="xsd:int"/>

<xsd:element name="gekauft" type="xsd:boolean"/>

</xsd:sequence>

</xsd:complexType>

</types>

Page 5: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

4

Die folgende Abbildung zeigt das fertige Schema.

Das Schema kann unter Autos.xsd gespeichert werden.

2.2 XML-Datei erstellen

Mit dem erstellten Schema kann nun eine (oder auch mehrere) XML-Datei-Instanzen erzeugt

werden. Es ist sinnvoll die XML-Datei im selben Verzeichnis wie die Schema-Datei

abzulegen, denn beide Dateien werden zukünftig als Einheit betrachtet.

Eine neue XML-Datei kann am einfachsten mit XMLSpy oder einem anderen validierenden

XML-Editor erstellt werden. In XMLSpy gehen wir dazu wie folgt vor:

Schema Autos.xsd in XMLSpy öffnen

Mit DTD/Schema -> Generate Sample XML File… erstellen wir die XML-Datei

<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="AutoArrayItems" type="AutoArray"/>

<xsd:complexType name="AutoArray">

<xsd:sequence> <xsd:element name="AutoArrayItem" type="Auto" minOccurs="1" maxOccurs="unbounded"/>

</xsd:sequence>

</xsd:complexType>

<xsd:complexType name="Auto">

<xsd:sequence>

<xsd:element name="autoID" type="xsd:long"/>

<xsd:element name="farbe" type="xsd:string"/>

<xsd:element name="anzahlSitze" type="xsd:int"/>

<xsd:element name="gekauft" type="xsd:boolean"/>

</xsd:sequence>

</xsd:complexType>

</xsd:schema>

Page 6: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

5

Attribut xsi:noNamespaceSchemaLocation ändern zu Autos.xsd

Überflüssige Kommentare löschen

Nun können entsprechend dem Schema ein paar Listeneinträge geschrieben werden. Die

fertige XML-Datei sollte dann etwa so aussehen.

Page 7: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

6

2.3 XML-Datei und Schema in Eclipse-Projekt integrieren

Das WAR-Archiv des Web Services soll später überall (auf verschiedenen Tomcats) laufen.

Dafür ist es nötig, die XML-Datei Autos.xml und die zugehörige Schema-Datei Autos.xsd in

das Web Service Projekt zu integrieren.

In Eclipse erstellen wir unter WebContent einen Ordner data und ziehen dann aus dem

Filesystem die beiden Dateien in diesen Ordner.

<?xml version="1.0" encoding="UTF-8"?>

<AutoArrayItems xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="Autos.xsd">

<AutoArrayItem>

<autoID>1</autoID>

<farbe>rot</farbe>

<anzahlSitze>4</anzahlSitze>

<gekauft>false</gekauft>

</AutoArrayItem>

<AutoArrayItem>

<autoID>2</autoID>

<farbe>blau</farbe>

<anzahlSitze>5</anzahlSitze>

<gekauft>true</gekauft>

</AutoArrayItem>

<AutoArrayItem>

<autoID>3</autoID>

<farbe>dunkelorange</farbe>

<anzahlSitze>8</anzahlSitze>

<gekauft>true</gekauft>

</AutoArrayItem>

<AutoArrayItem>

<autoID>4</autoID>

<farbe>rosa</farbe>

<anzahlSitze>3</anzahlSitze>

<gekauft>true</gekauft>

</AutoArrayItem>

<AutoArrayItem>

<autoID>5</autoID>

<farbe>gruen</farbe>

<anzahlSitze>5</anzahlSitze>

<gekauft>true</gekauft>

</AutoArrayItem>

<AutoArrayItem>

<autoID>6</autoID>

<farbe>hellweiss</farbe>

<anzahlSitze>2</anzahlSitze>

<gekauft>true</gekauft>

</AutoArrayItem>

</AutoArrayItems>

</AutoArrayItems>

Page 8: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

7

3 Web-Service Klasse AutoKaufSoapBindingImpl Erinnern wir uns an die Implementierungsklasse AutoKaufSoapBindingImpl des Web

Service Tutorials. Hier sind die drei Methoden alleAutosAnzeigen, kaufeAuto und

verkaufeAuto bereits implementiert. Zum Testen hatten wir schon ein wenig Funktionalität

hinterlegt.

3.1 Methode alleAutosAnzeigen

In der Methode alleAutosAnzeigen wird z. B. ein Array von Autos erzeugt und bei einer

Anfrage zurückgegeben. Das wird auch weiter so bleiben, mit dem Unterschied, dass wir die

Array-Daten (genauer das gesamte Array) aus der XML-Datei holen.

Mit leichten Änderungen sieht die Methode alleAutosAnzeigen nun wie folgt aus.

Page 9: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

8

Interessant ist hier nur der Methodenaufruf leseDatensaetze. Er führt die entsprechende

Methode aus, die das Array aus der XML-Datei erzeugt.

private Auto[] leseDatensaetze() { return null;}

Diese Methode werden wir weiter unten im Tutorial implementieren.

3.2 Methoden kaufeAuto und verkaufeAuto

Schauen wir uns die beiden Methoden kaufeAuto und verkaufeAuto an – zunächst

kaufeAuto.

Die Methode kaufeAuto wird mit dem Parameter autoID aufgerufen. Diese ID muss

natürlich in der XML-Datei eindeutig sein.

Wir verwenden hier auch wieder die Methode leseDatensaetze um das Array zu

bekommen. Wenn wir das Array erhalten haben, gehen wir es iterativ durch, bis zu dem Auto

mit der entsprechenden ID. Ist der Verkaufsstatus dieses Autos bereits true (also gekauft),

ist der Kauf nicht erfolgreich. Kann man es noch kaufen, wird hier der Status auf true

gesetzt.

Die Entscheidung, ob die Methode kaufeAuto erfolgreich ist, hängt nun noch davon ab, ob

das veränderte Array auch wieder als XML-Datei geschrieben werden kann.

Das schreiben erledigt die Methode schreibeDatensaetze, die wir uns auch weiter unten

noch genauer ansehen.

private boolean schreibeDatensaetze(Auto[] autos){ return false;}

Die Methode verkaufeAuto kann nun analog implementiert werden.

public boolean kaufeAuto(long autoID) throws java.rmi.RemoteException {

Auto[] autos = leseDatensaetze();

if (autos!=null) {

for (int i=0; i<autos.length; i++){

Auto auto = autos[i];

if (auto.getAutoID()!=autoID) continue;

if (auto.isGekauft()) break;

auto.setGekauft(true);

return schreibeDatensaetze(autos);

}

}

return false;

}

public AKWS1011GXX.AutoKauf.Types.Auto[] alleAutosAnzeigen() throws

java.rmi.RemoteException {

Auto[] autos = leseDatensaetze();

if(autos == null) return null;

return autos;

}

Page 10: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

9

3.3 Methode generiereXMLDateipfad

Mit der Methode generiereXMLDateipfad generieren wir den absoluten Dateipfad relativ

von der Class-Datei AutoKaufSoapBindingImpl.class.

Die XML-Datei Autos.xml und das zugehörige Schema haben wir zwar weiter oben in diesem

Tutorial in das Verzeichnis <ECLIPSE_WORKSPACE>\AKWS1011GXX\WebContent\data

verschoben, aber wir können natürlich nicht davon ausgehen das dieser Pfad auch auf dem

Zielsystem derselbe ist. Außerdem werden bereits bei unserem Eclipse-Projekt der gesamte

Web Content für die Tomcat-Plugin-Ausführung in den temporären Ordner

D:\...\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\webapps\AKWS1011GXX\ kopiert.

Kurz, wenn das WAR-Archiv später überall laufen soll, muss der Pfad der XML-Dateien

dynamisch generiert werden. Das bedarf ein wenig Bastelaufwand, wie der folgende Code

zeigt.

Zuerst lassen wir uns den Klassennamen

AKWS1011GXX.AutoKauf.AutoKaufSoapBindingImpl geben. Der Package-Name steckt

schon mit drin. Daraus erzeugen wir den relativen Klassenpfad

/AKWS1011GXX/AutoKauf/AutoKaufSoapBindingImpl.class

Nun lassen wir uns den absoluten Klassenpfad geben und ‚ziehen’ den relativen Klassenpfad

davon ab und landen hier /D:/.../.metadata/..../tmp0/webapps/AKWS1011GXX/WEB-

INF/classes.

Nun hangeln wir uns noch zum Projekt-Verzeichnis /D:/.../.metadata/..../tmp0/

webapps/AKWS1011GXX – das entspricht im Eclipse-Projekt dem Ordner WebContent.

Als nächstes wird der relative Dateipfad einheitlich mit Slashs geschrieben (Bsp.:

data\Autos.xml data/Autos.xml) und wir schreiben einen Slash voran, falls nicht schon da

( /data/Autos.xml).

Zum Schluss fügen wir den modifizierten relativen Pfad der XML-Datei hinzu

(D:/.../.metadata/..../tmp0/webapps/AKWS1011GXX /data/Autos.xml).

private String generiereXMLDateipfad(String dateipfadrelativ) {

String klassenname = this.getClass().getName();

String klassenpfadrelativ = "/" + klassenname.replace(".","/") + ".class";

String klassenpfadabsolut =

getClass().getResource(klassenpfadrelativ).getFile();

String classespfad = klassenpfadabsolut.replace(klassenpfadrelativ, "");

String buildpfad = classespfad.substring(0, classespfad.lastIndexOf("/"));

String projektpfad = buildpfad.substring(0, buildpfad.lastIndexOf("/"));

dateipfadrelativ=dateipfadrelativ.replace("\\", "/");

if (dateipfadrelativ.charAt(0)!='/') dateipfadrelativ = "/"

+ dateipfadrelativ;

String dateipfadabsolut = projektpfad + dateipfadrelativ;

dateipfadabsolut = dateipfadabsolut.replace("%20", " ");

return dateipfadabsolut;

}

Page 11: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

10

Dummerweise sind darin enthaltene Leerzeichen als %20 geschrieben. 20 entspricht dem

Hexadezimal-Wert des ASCII-Codes 32 für das Leerzeichen. Das müssen wir also auch noch

ändern.

Die Methode werden wir nun verwenden um die XML-Datei auszulesen und zu speichern.

3.4 Methode leseDatensaetze

Diese Methode liefert uns aus den Einträgen der XML-Datei (AutoArrayItems) ein Array

mit Autos (Auto.java).

Grob besteht die Methode aus 4 Teilen:

- Validierendes Einlesen der XML-Datei

- Erstellen des Arrays

- Abfangen von Exceptions (Fehlerbehandlung)

- Rückgabe des Arrays

Validierendes Einlesen der XML-Datei

Dieser Teil entspricht komplett der JAXP-API zur Erstellung eines DOM-Parsers, der in der

Lage ist, die einzulesende XML-Datei gegen ein XML Schema zu validieren.

Erstellen des Arrays

Der im vorhergehenden Schritt erstellte Parser erzeugt eine XML-Dokumentenstruktur

(document) im Speicher auf der wir nun arbeiten können. Dazu werden die Elemente iterativ

durchgegangen und die entsprechenden Einträge herausgesucht.

Jedes XML-Dokument besitzt exakt ein Root-Element. In diesem Fall heißt das Root-Element

AutoArrayItems und deutet schon an, dass es mehrere AutoArrayItem-Kindelemente

beinhalten kann. Im ersten Schritt wird also das Root-Element des Dokumentes

(AutoArrayItems) zurückgegeben. Dieses wird iterativ durchgegangen und jedes

AutoArrayItem herausgesucht.

Nun könnte die Frage auftauchen, warum wir erst noch prüfen, ob es sich um ein

AutoArrayItem handelt. Laut der Schema-Datei waren doch nur AutoArrayItem-

Elemente als Kindknoten zugelassen. Und nach der Validierung müsste man doch erst recht

davon ausgehen können. Das ist zwar richtig. Aber außer den offiziellen Elementen

private Auto[] leseDatensaetze() {

Auto[] autos=null;

try {

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

factory.setValidating(true);

factory.setNamespaceAware(true);

factory.setAttribute(

"http://java.sun.com/xml/jaxp/properties/schemaLanguage",

"http://www.w3.org/2001/XMLSchema");

DocumentBuilder builder = factory.newDocumentBuilder();

Document document = builder.parse(

new File(generiereXMLDateipfad("/data/Autos.xml")));

...

Page 12: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

11

schleichen sich immer noch Text-Knoten in das XML-Dokument hinein (mit

Zeilenumbrüchen und Tabulatoren als Inhalt), die dafür sorgen, dass die XML-Datei schön

gelesen werden kann (pretty-print). Im Normalfall bestände sonst so ein XML-Dokument aus

nur einer Zeile. Wie auch immer, solche Textknoten müssen ignoriert werden.

In der zweiten for-Schleife werden die (Unter-) Elemente eines jeden AutoArrayItem

durchlaufen. Das sind natürlich genau die Eigenschaften der Bean-Klasse Auto (long

autoID, String farbe, int anzahlSitze, boolean gekauft).

Bei jedem gefundenen AutoArrayItem wird die ArrayList autoarray um ein Auto

erweitert.

Da zur Übergabe ein Array benötigt wird, muss am Ende dieses Abschnitts noch die

ArrayList vom Typ Auto in ein Array vom Typ Auto[] umgewandelt werden.

autos = (Auto[]) autoarray.toArray( new Auto[0] );

Leider gibt es in Java keine schönere Möglichkeit als diese.

...

Element rootElement = document.getDocumentElement();

NodeList nodeList1 = rootElement.getChildNodes();

ArrayList<Auto> autoarray=null;

autoarray = new ArrayList<Auto>();

Auto auto = null;

for (int i=0;i<nodeList1.getLength();i++) {

Node autoarrayitem = nodeList1.item(i);

if (!autoarrayitem.getNodeName().equals("AutoArrayItem")) continue;

auto = new Auto();

NodeList nodeList2 = autoarrayitem.getChildNodes();

for (int j=0;j<nodeList2.getLength();j++){

Node eigenschaft = nodeList2.item(j);

if (eigenschaft.getNodeName().equals("autoID"))

auto.setAutoID((long)Long.valueOf(eigenschaft.getTextContent()));

if (eigenschaft.getNodeName().equals("farbe"))

auto.setFarbe(eigenschaft.getTextContent());

if (eigenschaft.getNodeName().equals("anzahlSitze"))

auto.setAnzahlSitze((int)Integer

.valueOf(eigenschaft.getTextContent()));

if (eigenschaft.getNodeName().equals("gekauft"))

auto.setGekauft((boolean)Boolean

.valueOf(eigenschaft.getTextContent()));

}

autoarray.add(auto);

}

autos = (Auto[]) autoarray.toArray( new Auto[0] );

...

Page 13: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

12

Abfangen von Exceptions

ParserConfigurationExceptions können beim Erstellen des DocumentBuilders

auftreten, SAXExceptions und IOExceptions beim validierenden Einlesen (Parsen) der

XML-Datei.

Rückgabe des Arrays

Dazu ist nicht viel zu sagen, außer dass wenn alles geklappt hat, wird ein Array vom Typ

Auto[] zurückgegeben – wenn nicht, null.

3.5 Methode schreibeDatensaetze

Diese Methode schreibt ein übergebenes Auto[]-Array in eine XML-Datei.

Die Methode besteht grob aus 5 Teilen:

- Erstellen einer XML-Baum-Struktur (im Speicher)

- Erstellen des Root-Elements AutoArrayItems

- Füllen des Root-Elements mit AutoArrayItem-Einträgen

- Schreiben der XML-Datei

- Abfangen der Exceptions / Rückgabewert

Erstellen einer XML-Baum-Struktur (im Speicher)

Die Datenstruktur Document bildet den Rahmen für alle XML-Elemente.

Erstellen des Root-Elements

Jedes XML-Dokument hat genau ein Root-Element. In diesem Fall ist es das Element

AutoArrayItems. Im Root-Element des Dokumentes muss auch ein zugehöriges XML

Schema festgelegt werden, wenn die XML-Datei später gegen ein Schema validiert werden

soll. Dafür dienen die beiden setAttribute-Aufrufe.

private boolean schreibeDatensaetze(Auto[] autos){

if (autos==null) return false;

try {

DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

Document document = builder.newDocument();

...

...

return autos;

}

...

} catch (ParserConfigurationException pce) {

pce.printStackTrace();

} catch (SAXException se) {

se.printStackTrace();

} catch (IOException ioe) {

ioe.printStackTrace();

}

...

Page 14: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

13

Füllen des Root-Elements mit Einträgen

In diesem Abschnitt werden alle Elemente des übergebenen Arrays autos dem Root-Element

als AutoArrayItem-Kindelemente angehängt. Dem Element AutoArrayItem werden

wiederum die Attribute des Autos als Kind-Elemente angehängt.

Schreiben der XML-Datei

Nun wird das XML-Dokument document aus dem Speicher in das Filesystem geschrieben.

Dazu wird ein XSLT-Transformer verwendet, der die XML-Struktur in einen serialisierten

Outputstream umwandelt. Auch dieses Verfahren zur Speicherung der XML-Datei entspricht

der JAXP-API.

Leider unterstützt die JAXP-API derzeit kein Pretty-Print. Das bedeutet, dass die

geschriebene XML-Datei aus einer Zeile bestehen wird. Die meisten Parser bieten aber eine

entsprechende Funktion an.

...

TransformerFactory transFactory = TransformerFactory.newInstance();

Transformer transformer = transFactory.newTransformer();

DOMSource source = new DOMSource(document);

FileOutputStream fos = new FileOutputStream(new

File(generiereXMLDateipfad("/data/Autos.xml")));

StreamResult result = new StreamResult(fos);

transformer.transform(source,result);

...

...

for (int i=0; i<autos.length; i++) {

Auto auto = autos[i];

Node autoarrayitem;

autoarrayitem = root.appendChild(document.createElement("AutoArrayItem"));

autoarrayitem.appendChild(document.createElement("autoID"))

.setTextContent(String.valueOf(auto.getAutoID()));

autoarrayitem.appendChild(document.createElement("farbe"))

.setTextContent(auto.getFarbe());

autoarrayitem.appendChild(document.createElement("anzahlSitze"))

.setTextContent(String.valueOf(auto.getAnzahlSitze()));

autoarrayitem.appendChild(document.createElement("gekauft"))

.setTextContent(String.valueOf(auto.isGekauft()));

}

document.appendChild(root);

...

...

Element root =document.createElement("AutoArrayItems");

root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

root.setAttribute("xsi:noNamespaceSchemaLocation","Autos.xsd");

...

Page 15: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

14

Rückgebewert

Konnte die Methode erfolgreich ausgeführt werden, liefert sie true zurück. Traten

Exceptions auf, wird false zurückgeliefert.

Schauen wir uns zum Abschluss alle in dieser Klasse verwendeten Imports an.

3.6 Testen des XML-Dateizugriffs

An dieser Stelle haben wir die Implementierung der Methoden abgeschlossen und können nun

das gesamte Projekt testen.

Zum testen der Methode leseDatensaetze können wir uns im Browser die Einträge der

XML-Datei anzeigen lassen.

http://localhost/AKWS1011GXX/services/AutoKauf?method=alleAutosAnzeigen

...

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.rmi.RemoteException;

import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerConfigurationException;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

...

...

return true;

} catch( ParserConfigurationException pce ) {

pce.printStackTrace();

} catch( TransformerConfigurationException tce ) {

tce.printStackTrace();

} catch( TransformerException te ) {

te.printStackTrace();

} catch( FileNotFoundException fnfe ) {

fnfe.printStackTrace();

}

return false;

}

Page 16: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

15

Das Ergebnis sollte nun das folgende sein.

Aus diesem Ergebnis suchen wir uns einen Eintrag heraus wo gekauft gleich false ist - also

ein Auto, das wir noch kaufen können (z.B. autoID=1). Mit dem folgenden Aufruf werden

wir es ‚kaufen’.

http://localhost/AKWS1011GXX/services/AutoKauf?method=kaufeAuto&autoID=1

Das Ergebnis sollte das folgende sein.

Page 17: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

16

Wir erhalten also den Wert true zurück und erkennen damit zum einen, dass das Auto

erfolgreich gekauft werden konnte und zum anderen, dass die Methode

schreibeDatensaetze erfolgreich ausgeführt werden konnte – diese hätte ja sonst den

Wert false geliefert und somit zu dem Gesamtrückgabewert false der Methode

kaufeAuto geführt. Analog kann die Methode verkaufeAuto getestet werden.

4 Erstellen des Archivs AKWS1011GXX.war Bevor wir abschließend das WAR-Archiv erstellen, schauen wir uns zum Vergleich im

Package-Explorer die gesamte Dateistruktur noch einmal an.

Mit Rechtsklick auf das Projekt AKWS1011GXX Export -> WAR file erstellen wir das

entsprechende WAR-Archiv.

Page 18: XML-Datei für Web Service auslesen und schreiben 2 - XML... · XML-Datei für Web Service auslesen und schreiben Einleitung Anliegen dieses Tutorials ist das Einbinden einer XML-Datei

17

Zum Testen des Archivs können wir Eclipse beenden, die Datei AKWS1011GXX.war in den

Tomcat-WebApps-Ordner (<TOMCAT_ROOT>\WebApps\) verschieben und Tomcat als

Applikation (bzw. Dienst) starten. Im Browser können wir uns das Ergebnis ansehen.