Die folgende praktische Einführung demonstriert, wie Sie auf Webdienste mit der Java API für XML-Webdienste (JAX-WS) zugreifen.
Bevor Sie beginnen, benötigen Sie die JAX-WS-Tools von Sun. Wenn dieses Paket auf Ihren System nicht installiert ist, müssen
Sie die JAX-WS-Tools herunterladen und installieren. Um die JAX-WS-Tools herunterzuladen, gehen Sie zu http://java.sun.com/webservices/. Klicken Sie auf den Link für JAX-WS. Dies sollte Sie auf die Seite
Java-API für XML Webdienste bringen. Klicken Sie auf den Download Now-Link. Nachdem Sie das Softwarepaket heruntergeladen haben, installieren Sie es auf Ihrem System.
Dieses Beispiel wurde mit JAX-WS 2.1.3 für Windows entwickelt.
Für SQL Anywhere SOAP-Webdienste, auf die aus JAX-WS zugegriffen wird, muss das Format CONCRETE deklariert werden.
Führen Sie an der Eingabeaufforderung folgenden Befehl aus, um einen Personal Webserver zu starten. Ersetzen Sie Beispieldatenbank durch den tatsächlichen Speicherort der Beispieldatenbank. Die Option -xs http(port=80)
teilt dem Datenbankserver mit, HTTP-Anforderungen auf Port 80 anzunehmen. Wenn Sie bereits einen Webserver auf Port 80 laufen
haben, verwenden Sie eine andere Portnummer wie z.B. 8080 in dieser praktischen Einführung und geben Sie 8080 statt 80 bei
allen Portreferenzen an.
dbeng11 -xs http(port=80) Beispielverzeichnis\demo.db |
Starten Sie Interactive SQL und stellen Sie als DBA eine Verbindung mit der SQL Anywhere-Datenbank her. Führen Sie die folgenden Anweisungen aus:
Erstellen Sie eine gespeicherte Prozedur, die einige Spalten der Tabelle Employees auflistet.
CREATE PROCEDURE ListEmployees() RESULT ( EmployeeID INTEGER, Surname CHAR(20), GivenName CHAR(20), StartDate DATE, TerminationDate DATE ) BEGIN SELECT EmployeeID, Surname, GivenName, StartDate, TerminationDate FROM Employees; END; |
Legen Sie einen SOAP-Dienst fest, der diese gespeicherte Prozedur aufruft.
CREATE SERVICE "WS/EmployeeList" TYPE 'SOAP' FORMAT 'CONCRETE' EXPLICIT OFF DATATYPE OUT AUTHORIZATION OFF SECURE OFF USER DBA AS CALL ListEmployees(); |
Die EXPLICIT-Klausel kann nur mit einem SOAP- oder DISH-Dienst vom Typ CONCRETE verwendet werden. In diesem Beispiel gibt EXPLICIT OFF an, dass der entsprechende DISH-Dienst ein XML-Schema generieren soll, das das generische SimpleDataset-Objekt beschreibt. Die Option betrifft nur das generierte WSDL-Dokument. Später wird ein Beispiel behandelt, das EXPLICIT ON verwendet. Weitere Hinweise finden Sie unter Praktische Einführung: Datentypen mit JAX-WS verwenden.
DATATYPE OUT gibt an, dass explizite Datentypinformationen in der zurückgegebenen XML-Ergebnismenge generiert werden. Falls DATATYPE OFF angegeben worden wäre, würden alle Daten als "string" typisiert sein. Diese Option wirkt sich nicht auf das WSDL-Dokument aus, das generiert wird.
Da die Autorisierung deaktiviert ist, kann jeder diesen Dienst benutzen, ohne einen Benutzernamen mit Kennwort anzugeben. Die Befehle werden unter dem Benutzer DBA ausgeführt. Dieses Arrangement ist einfach, aber nicht sicher.
Erstellen Sie einen DISH-Dienst, der als Proxy für den SOAP-Dienst agiert und das WSDL-Dokument generiert.
CREATE SERVICE "WSDish" TYPE 'DISH' FORMAT 'CONCRETE' GROUP "WS" AUTHORIZATION OFF SECURE OFF USER DBA; |
Der SOAP- und der DISH-Dienst müssen beide das CONCRETE-Format haben. Da sich der EmployeeList-Dienst in der WS-Gruppe befindet, ist auch eine GROUP-Klausel enthalten.
Sehen Sie sich das WSDL an, das der DISH-Dienst automatisch erstellt. Um das zu erreichen, öffnen Sie einen Webbrowser und
navigieren zur folgenden URL: http://localhost:80/demo/WSDish. Der DISH-Dienst generiert automatisch ein WSDL-Dokument, das im Browser-Fenster angezeigt wird.
Beachten Sie besonders das SimpleDataset-Objekt, das vorgelegt wird, weil das Format des Dienstes CONCRETE und EXPLICIT auf OFF gesetzt ist. In einem späteren Schritt verwendet die wsimport-Anwendung diese Informationen, um eine SOAP 1.1-Clientschnittstelle für diesen Dienst zu generieren.
<s:complexType name="SimpleDataset">
<s:sequence>
<s:element name="rowset">
<s:complexType>
<s:sequence>
<s:element name="row" minOccurs="0" maxOccurs="unbounded">
<s:complexType>
<s:sequence>
<s:any minOccurs="0" maxOccurs="unbounded" />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType> |
In diesem Beispiel sind die Java-API für XML-Webdienste und das Sun Java 1.6.0 JDK auf Laufwerk C: installiert. Legen Sie die PATH-Umgebungsvariable so fest, dass sie die JAX-WS-Binärdateien ebenso wie den JDK einbezieht. Die Binärdateien befinden sich in den folgenden Verzeichnissen:
c:\Sun\jaxws-ri\bin c:\Sun\SDK\jdk\bin |
An einer Eingabeaufforderung legen Sie Ihre CLASSPATH-Umgebungsvariable fest.
SET classpath=.;C:\Sun\jaxws-ri\lib\jaxb-api.jar ;C:\Sun\jaxws-ri\lib\jaxws-rt.jar |
Der nächste Schritt generiert die Schnittstelle, die zum Aufruf des Webdiensts erforderlich ist.
An derselben Eingabeaufforderung erstellen Sie ein neues Projektverzeichnis und machen dieses Verzeichnis zu Ihrem aktuellen Verzeichnis. Führen Sie den folgenden Befehl in diesem Verzeichnis aus.
wsimport -keep -Xendorsed "http://localhost:80/demo/WSDish" |
Das wsimport-Tool ruft das WSDL-Dokument von der angegebenen URL ab, generiert die Java-Dateien, die die Schnittstelle dafür festlegen, und kompiliert sie dann.
Die Option keep teilt wsimport mit, die .java-Dateien nicht zu löschen. Ohne diese Option werden diese Dateien gelöscht, nachdem die entsprechenden .class-Dateien generiert wurden. Das Aufbewahren dieser Dateien erleichert es, den Aufbau der Schnittstelle zu untersuchen.
Die Option Xendorsed ermöglicht es Ihnen, die JAX-WS 2.1 API mit JDK6 zu verwenden.
Sobald dieser Befehl abgeschlossen ist, finden Sie die neue Unterverzeichnisstruktur namens localhost\demo\ws vor, die die folgenden Java-Dateien sowie ihre kompilierten .class-Versionen enthält.
EmployeeList.java EmployeeListResponse.java FaultMessage.java ObjectFactory.java package-info.java SimpleDataset.java WSDish.java WSDishSoapPort.java |
Speichern Sie den folgenden Java-Quellcode in SASoapDemo.java. Vergewissern Sie sich, dass sich diese Datei in dem Verzeichnis befindet, das auch das von wsimport-Tool erstellte Unterverzeichnis localhost enthält.
// SASoapDemo.java illustrates a web service client that // calls the WSDish service and prints out the data. import java.util.*; import javax.xml.ws.*; import org.w3c.dom.Element; import org.w3c.dom.Node; import localhost.demo.ws.*; public class SASoapDemo { @WebServiceRef( wsdlLocation= "http://localhost:8080/demo/WSDish" ) public static void main( String[] args ) { try { WSDish service = new WSDish(); Holder<SimpleDataset> response = new Holder<SimpleDataset>(); Holder<Integer> sqlcode = new Holder<Integer>(); WSDishSoapPort port = service.getWSDishSoap(); // This is the SOAP service call to EmployeeList port.employeeList( response, sqlcode ); localhost.demo.ws.SimpleDataset result = response.value; SimpleDataset.Rowset rowset = result.getRowset(); List<SimpleDataset.Rowset.Row> rows = rowset.getRow(); for ( int i = 0; i < rows.size(); i++ ) { SimpleDataset.Rowset.Row row = rows.get( i ); List<Object> cols = row.getAny(); System.out.println( "Number of columns=" + cols.size() ); for ( int j = 0; j < cols.size(); j++ ) { // Column data is contained as a SOAPElement Element col = (Element)cols.get(j); System.out.print(col.getLocalName() + "=" ); Node node = col.getFirstChild(); if( node == null ) { System.out.println( "(null)" ); } else { System.out.println( node.getNodeValue() ); } } System.out.println(); } } catch (Exception x) { x.printStackTrace(); } } } |
Wenn der Webserver mit einer anderen Portnummer, wie z.B. mit 8080, gestartet werden soll, müssen Sie die Quellenzeile import localhost
ähnlich wie folgt ändern:
import localhost._8080.demo.ws.*; |
Kompilieren Sie SASoapDemo.java.
javac SASoapDemo.java |
Führen Sie die kompilierte Klassendatei aus.
java SASoapDemo |
Wenn die Anwendung ihre Anforderung an den Webserver sendet, erhält sie als Antwort eine XML-Ergebnismenge, die aus EmployeeListResult mit einer Zeilengruppe besteht, die mehrere Zeileneinträge enthält. Ebenfalls in der Antwort enthalten ist das sqlcode-Ergebnis der ausgeführten Abfrage. Ein Beispiel für die Antwort sieht folgendermaßen aus.
<tns:EmployeeListResponse> <tns:EmployeeListResult xsi:type='tns:SimpleDataset'> <tns:rowset> <tns:row>...</tns:row> . . . <tns:row>...</tns:row> </tns:rowset> </tns:EmployeeListResult> <tns:sqlcode>0</tns:sqlcode> </tns:EmployeeListResponse> |
Jede Zeile in der Zeilengruppe wird in dem nachstehend gezeigten Format gesendet.
<tns:row> <tns:EmployeeID xsi:type="xsd:int">1751</tns:EmployeeID> <tns:Surname xsi:type="xsd:string">Ahmed</tns:Surname> <tns:GivenName xsi:type="xsd:string">Alex</tns:GivenName> <tns:StartDate xsi:type="xsd:date">1994-07-12-04:00</tns:StartDate> <tns:TerminationDate xsi:type="xsd:date">2008-04-18-04:00 </tns:TerminationDate> </tns:row> |
Beachten Sie, dass der Spaltenname und der Datentyp enthalten sind.
Sie können die oben angezeigte Antwort verfolgen, indem Sie eine Proxy-Software verwenden, die das XML-Nachrichtenaufkommen protokolliert. Der Proxy steht zwischen Ihrer Clientanwendung und dem Webserver.
Die EmployeeList-Ergebnismenge wird von der SASoapDemo-Anwendung als (Typ)Spaltenname=Wert-Paare angezeigt. Es sollten einige Zeilen ähnlich den folgenden generiert und ausgegeben werden.
Die EmployeeList-Ergebnismenge wird in der Form von Spaltenname=Wert-Paaren angezeigt. Es sollten einige Zeilen ähnlich den folgenden generiert und ausgegeben werden.
Number of columns=4 EmployeeID=102 Surname=Whitney GivenName=Fran StartDate=1984-08-28-04:00 Number of columns=4 EmployeeID=105 Surname=Cobb GivenName=Matthew StartDate=1985-01-01-05:00 . . . Number of columns=4 EmployeeID=1740 Surname=Nielsen GivenName=Robert StartDate=1994-06-24-04:00 Number of columns=5 EmployeeID=1751 Surname=Ahmed GivenName=Alex StartDate=1994-07-12-04:00 TerminationDate=2008-04-18-04:00 |
Beachten Sie, dass die TerminationDate-Spalte nur gesendet wird, wenn ihr Wert NULL ist. Bei diesem Beispiel wurde die letzte Zeile in der Employees-Tabelle geändert, um ein Nicht-NULL-Beendigungsdatum festzulegen.
Beachten Sie auch, dass die Datumswerte einen Offset von der UTC-Zeit einbeziehen. Im obenstehenden Beispiel befindet sich der Server in der North American Eastern-Zeitzone. Dies ist 5 Stunden früher als UTC-Zeit (-05:00) bei Datumsangaben, wenn keine Sommerzeit gilt, und 4 Stunden früher als UTC-Zeit (-04:00) bei Datumsangaben, wenn Sommerzeit gilt.
Kommentieren Sie diese Seite in DocCommentXchange. Senden Sie uns Feedback über diese Seite via E-Mail. |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |