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 SQLDatenbank 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 2.2 2.3 3 3.1 3.2 3.3 3.4 3.5 3.6 4 XML Schema erstellen _________________________________________ 2 XML-Datei erstellen ___________________________________________ 4 XML-Datei und Schema in Eclipse-Projekt integrieren_______________ 6 WEB-SERVICE KLASSE AUTOKAUFSOAPBINDINGIMPL _____ 7 Methode alleAutosAnzeigen ____________________________________ 7 Methoden kaufeAuto und verkaufeAuto __________________________ 8 Methode generiereXMLDateipfad ________________________________ 9 Methode leseDatensaetze _____________________________________ 10 Methode schreibeDatensaetze _________________________________ 12 Testen des XML-Dateizugriffs __________________________________ 14 ERSTELLEN DES ARCHIVS AKWS1011GXX.WAR __________ 16 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. 1 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. 2 <?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> … 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. 3 Die folgende Abbildung zeigt das fertige Schema. <?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> 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 4 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. 5 <?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> 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. 6 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. 7 public AKWS1011GXX.AutoKauf.Types.Auto[] alleAutosAnzeigen() throws java.rmi.RemoteException { Auto[] autos = leseDatensaetze(); if(autos == null) return null; return autos; } 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. 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; } 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. 8 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. 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; } Zuerst lassen wir uns den Klassennamen AKWS1011GXX.AutoKauf.AutoKaufSoapBindingImpl geben. Der Package-Name steckt schon mit drin. Daraus erzeugen wir den /AKWS1011GXX/AutoKauf/AutoKaufSoapBindingImpl.class relativen Klassenpfad Nun lassen wir uns den absoluten Klassenpfad geben und ‚ziehen’ den relativen Klassenpfad davon ab und landen hier /D:/.../.metadata/..../tmp0/webapps/AKWS1011GXX/WEBINF/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). 9 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. 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"))); ... 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 AutoArrayItemElemente 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 10 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. ... 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] ); ... 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. 11 Abfangen von Exceptions ParserConfigurationExceptions können beim Erstellen des DocumentBuilders auftreten, SAXExceptions und IOExceptions beim validierenden Einlesen (Parsen) der XML-Datei. ... } catch (ParserConfigurationException pce) { pce.printStackTrace(); } catch (SAXException se) { se.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } ... 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. ... return autos; } 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. private boolean schreibeDatensaetze(Auto[] autos){ if (autos==null) return false; try { DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); ... 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. 12 ... Element root =document.createElement("AutoArrayItems"); root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); root.setAttribute("xsi:noNamespaceSchemaLocation","Autos.xsd"); ... 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. ... 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); ... 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. ... 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); ... 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. 13 Rückgebewert Konnte die Methode erfolgreich ausgeführt werden, liefert sie true zurück. Traten Exceptions auf, wird false zurückgeliefert. ... return true; } catch( ParserConfigurationException pce ) { pce.printStackTrace(); } catch( TransformerConfigurationException tce ) { tce.printStackTrace(); } catch( TransformerException te ) { te.printStackTrace(); } catch( FileNotFoundException fnfe ) { fnfe.printStackTrace(); } return false; } Schauen wir uns zum Abschluss alle in dieser Klasse verwendeten Imports an. ... import import import import import import java.io.File; java.io.FileNotFoundException; java.io.FileOutputStream; java.io.IOException; java.rmi.RemoteException; java.util.ArrayList; import import import import import import import import import javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory; javax.xml.parsers.ParserConfigurationException; javax.xml.transform.Transformer; javax.xml.transform.TransformerConfigurationException; javax.xml.transform.TransformerException; javax.xml.transform.TransformerFactory; javax.xml.transform.dom.DOMSource; javax.xml.transform.stream.StreamResult; import import import import import ... org.w3c.dom.Document; org.w3c.dom.Element; org.w3c.dom.Node; org.w3c.dom.NodeList; org.xml.sax.SAXException; 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 14 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. 15 Wir erhalten also den Wert true zurück und erkennen damit zum einen, dass erfolgreich gekauft werden konnte und zum anderen, dass die schreibeDatensaetze erfolgreich ausgeführt werden konnte – diese hätte ja Wert false geliefert und somit zu dem Gesamtrückgabewert false der kaufeAuto geführt. Analog kann die Methode verkaufeAuto getestet werden. das Auto Methode sonst den Methode 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. 16 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. 17