Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » SQL Anywhere Server - Programmierung » SQL Anywhere Datenzugriff-APIs » SQL Anywhere-Webdienste

 

Praktische Einführung: Zugriff auf Webdienste von JAX-WS

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 [external link] http://java.sun.com/webservices/. Klicken Sie auf den Link für JAX-WS. Dies sollte Sie auf die Seite [external link] 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.

♦  So erstellen Sie SOAP- und DISH-Dienste
  1. 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
  2. Starten Sie Interactive SQL und stellen Sie als DBA eine Verbindung mit der SQL Anywhere-Datenbank her. Führen Sie die folgenden Anweisungen aus:

    1. 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;
    2. 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.

    3. 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.

  3. 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: [external link] 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>
♦  So generieren Sie eine JAX-WS-Schnittstelle für diese Webdienste
  1. 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
  2. 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
  3. 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
♦  So verwenden Sie die generierte JAX-WS-Schnittstelle
  1. 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.*;
  2. Kompilieren Sie SASoapDemo.java.

    javac SASoapDemo.java
  3. 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.

    Einen Proxy verwenden

    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.