Apache Axis


Apache Axis

Java Web Service (JWS)

Ein einfacher Java Web Service: CarStore.jws

public class CarStore {

    private static String[] cars = null; 

    public CarStore() {
        if ( cars != null ) {
            return;
        }
        cars = new String[] {
            "Opel",
            "Porsche",
            "BMW",
            "Audi",
            "VW",
            "Mazda",
            "Toyota",
            "Volvo"
        };
    }

    public String getCar( int iCar ) {
        if ( cars == null ) {
            return "uninitialized";
        }
        if ( iCar < 0 || cars.length <= iCar ) {
            return "out of bounds";
        }
        return cars[ iCar ];
    } 

    public String getCars( ) {
        if ( cars == null ) {
            return "uninitialized";
        }
        StringBuffer result = new StringBuffer();
        for ( int i = 0; i < cars.length; i++ ) {
            result.append(" " + cars[i] );
        }
        return result.toString();
    } 

    public String[] getCarArray( ) {
        if ( cars == null ) {
            return new String[] { "uninitialized" };
        }
        return cars;
    } 

    public void setAppendCar(String car) {
        String[] newCars = new String[ cars.length + 1];
        for ( int i = 0; i < cars.length; i++ ) {
            newCars[i] = cars[i];
        }
        newCars[ newCars.length -1 ] = car;
        cars = newCars;
        return;
    } 
}

Das AxisServlet stellt mit dem Parameter wsdl (der Aufruf URL ist CarStor.jws?wsdl) folgende WSDL Beschreibung des Service zur Verfügung:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions 
  targetNamespace="http://localhost:8080/axis/CarStore.jws" 
  xmlns="http://schemas.xmlsoap.org/wsdl/" 
  xmlns:apachesoap="http://xml.apache.org/xml-soap" 
  xmlns:impl="http://localhost:8080/axis/CarStore.jws" 
  xmlns:intf="http://localhost:8080/axis/CarStore.jws" 
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
  xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <schema 
      targetNamespace="http://localhost:8080/axis/CarStore.jws" 
      xmlns="http://www.w3.org/2001/XMLSchema">
      <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
      <complexType name="ArrayOf_xsd_string">
        <complexContent>
          <restriction base="soapenc:Array">
            <attribute ref="soapenc:arrayType" 
                       wsdl:arrayType="xsd:string[]"/>
          </restriction>
        </complexContent>
      </complexType>
    </schema>
  </wsdl:types>
  <wsdl:message name="getCarResponse">
    <wsdl:part name="getCarReturn" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="setAppendCarResponse">
  </wsdl:message>
  <wsdl:message name="getCarArrayRequest">
  </wsdl:message>
  <wsdl:message name="setAppendCarRequest">
    <wsdl:part name="car" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="getCarsRequest">
  </wsdl:message>
  <wsdl:message name="getCarRequest">
    <wsdl:part name="iCar" type="xsd:int"/>
  </wsdl:message>
  <wsdl:message name="getCarArrayResponse">
    <wsdl:part name="getCarArrayReturn" type="impl:ArrayOf_xsd_string"/>
  </wsdl:message>
  <wsdl:message name="getCarsResponse">
    <wsdl:part name="getCarsReturn" type="xsd:string"/>
  </wsdl:message>
  <wsdl:portType name="CarStore">
    <wsdl:operation name="getCar" parameterOrder="iCar">
      <wsdl:input message="impl:getCarRequest" name="getCarRequest"/>
      <wsdl:output message="impl:getCarResponse" name="getCarResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getCarArray">
      <wsdl:input message="impl:getCarArrayRequest" name="getCarArrayRequest"/>
      <wsdl:output message="impl:getCarArrayResponse" name="getCarArrayResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getCars">
      <wsdl:input message="impl:getCarsRequest" name="getCarsRequest"/>
      <wsdl:output message="impl:getCarsResponse" name="getCarsResponse"/>
    </wsdl:operation>
    <wsdl:operation name="setAppendCar" parameterOrder="car">
      <wsdl:input message="impl:setAppendCarRequest" name="setAppendCarRequest"/>
      <wsdl:output message="impl:setAppendCarResponse" name="setAppendCarResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="CarStoreSoapBinding" type="impl:CarStore">
    <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getCar">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getCarRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://DefaultNamespace" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getCarResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://localhost:8080/axis/CarStore.jws" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
  <wsdl:binding name="CarStoreSoapBinding" type="impl:CarStore">
    <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getCar">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getCarRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://DefaultNamespace" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getCarResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://localhost:8080/axis/CarStore.jws" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="getCarArray">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getCarArrayRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://DefaultNamespace" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getCarArrayResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://localhost:8080/axis/CarStore.jws" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="getCars">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getCarsRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://DefaultNamespace" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getCarsResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://localhost:8080/axis/CarStore.jws" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="setAppendCar">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="setAppendCarRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
            namespace="http://DefaultNamespace" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="setAppendCarResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8080/axis/CarStore.jws" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="CarStoreService">
    <wsdl:port binding="impl:CarStoreSoapBinding" name="CarStore">
      <wsdlsoap:address location="http://localhost:8080/axis/CarStore.jws"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

mit dem Aufruf CarStore.jws?method=getCar&x=0 erhält man folgende Antwort

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <getCarResponse 
     soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <getCarReturn xsi:type="xsd:string">Opel</getCarReturn>
  </getCarResponse>
 </soapenv:Body>
</soapenv:Envelope>

mit dem Aufruf CarStore.jws?method=getCars erhält man folgende Antwort

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <getCarsResponse 
    soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <getCarsReturn 
     xsi:type="xsd:string"> 
      Opel Porsche BMW Audi VW Mazda Toyota Volvo
   </getCarsReturn>
  </getCarsResponse>
 </soapenv:Body>
</soapenv:Envelope>

mit dem Aufruf CarStore.jws?method=getCarArray erhält man folgende Antwort

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <getCarArrayResponse 
     soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <getCarArrayReturn 
      xsi:type="soapenc:Array" 
      soapenc:arrayType="xsd:string[8]" 
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
    <item>Opel</item>
    <item>Porsche</item>
    <item>BMW</item>
    <item>Audi</item>
    <item>VW</item>
    <item>Mazda</item>
    <item>Toyota</item>
    <item>Volvo</item>
   </getCarArrayReturn>
  </getCarArrayResponse>
 </soapenv:Body>
</soapenv:Envelope>

mit dem Aufruf CarStore.jws?method=setAppendCar&x=DaimlerChrysler erhält man folgende Antwort

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <setAppendCarResponse 
    soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
 </soapenv:Body>
</soapenv:Envelope>

der Inhalt des Objekts CarStor schient sich aber nicht zu ändern

Java Web Service Client

Ein einfacher Client, der aus dem CarStore WS, ein Auto ausliest: CarStoreGetCar

import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.rpc.ServiceException;

public class CarStoreGetCar {

    final static String carStoreUrl = 
          "http://localhost:8090/axis/services/CarStore";
// or     "http://localhost:8090/axis/CarStore.jws";
    final static String operation = "getCar";

    public static void main(String[] args) {

        Service service = new Service();
        Integer carNo = new Integer( 2 );
        Object[] params = new Object[] { carNo };
        String answer = "";

        try {
            URL url = new URL( carStoreUrl );
            Call call = (Call) service.createCall();

            call.setTargetEndpointAddress( url );
            call.setOperationName( operation );

            answer = (String) call.invoke( params );
            System.out.println("gesuchtes Auto = " 
                               + answer);
        } catch(MalformedURLException e) {
            e.printStackTrace();
        } catch(ServiceException e) {
            e.printStackTrace();
        } catch(RemoteException e) {
            e.printStackTrace();
        }
    }
}

Wird axis/service/CarStore angesprochen muss der Service mit WSDD (siehe unten) beschrieben und deployed worden sein.

Wird axis/CarStore.jws angesprochen, dann wurde der entsprechende Service mit WSDD (siehe unten) automatisch beschrieben und deployed.

Die Ausgabe ist z.B.

gesuchtes Auto = BMW

Der Client erzeugt folgende SOAP Anfrage

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <getCar soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <arg0 xsi:type="xsd:int">2</arg0>
  </getCar>
 </soapenv:Body>
</soapenv:Envelope>

Der Web Service antwortet mit folgender SOAP Nachricht

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <getCarResponse 
    soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <getCarReturn xsi:type="xsd:string">BMW</getCarReturn>
  </getCarResponse>
 </soapenv:Body>
</soapenv:Envelope>

Bei der Operation getCars erzeugt der Client folgenden SOAP Body in der Anfrage

<soapenv:Body>
  <getCars 
    soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</soapenv:Body>

und erhält folgende Antwort im SOAP Body

<soapenv:Body>
  <getCarsResponse 
     soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <getCarsReturn xsi:type="xsd:string"> Opel Porsche BMW Audi 
       VW Mazda Toyota Volvo</getCarsReturn>
  </getCarsResponse>
</soapenv:Body>

Bei der Operation getCarArray erzeugt der Client folgenden SOAP Body in der Anfrage

<soapenv:Body>
  <getCarArray
    soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</soapenv:Body>

Die Anfrage lässt sich genau so gut an JWS stellen, dabei wird der gleiche SOAP Body wie oben verwendet.

Die main-Methode ist wie folgt zu ändern:

 final static String carStoreUrl = 
          "http://localhost:8090/axis/CarStore.jws";
//          "http://localhost:8090/axis/services/CarStore";
 ...
       answer = (String[]) call.invoke( params );
       System.out.println("gefundene Autos:");
       for ( int i = 0; i < answer.length; i++ ) {
           System.out.println("Auto[" + i +  "] = " + answer[i]);
       }
 ...

Die Antwort ist jetzt ein SOAP String Array

<soapenv:Body>
  <getCarArrayResponse 
     soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <getCarArrayReturn 
      xsi:type="soapenc:Array" 
      soapenc:arrayType="xsd:string[8]"  
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
    <item>Opel</item>
    <item>Porsche</item>
    <item>BMW</item>
    <item>Audi</item>
    <item>VW</item>
    <item>Mazda</item>
    <item>Toyota</item>
    <item>Volvo</item>
   </getCarArrayReturn>
  </getCarArrayResponse>
 </soapenv:Body>

Die Ausgabe des Clients ist dann

gefundene Autos:
Auto[0] = Opel
Auto[1] = Porsche
Auto[2] = BMW
Auto[3] = Audi
Auto[4] = VW
Auto[5] = Mazda
Auto[6] = Toyota
Auto[7] = Volvo

Bei der Operation setAppendCar erzeugt der Client folgenden SOAP Body in der Anfrage

<soapenv:Body>
  <setAppendCar 
     soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <arg0 xsi:type="xsd:string">Renault</arg0>
  </setAppendCar>
</soapenv:Body>

Die Antwort ist leer, da es sich um eine void-Methode handelt, und sieht wie folgt aus

<soapenv:Body>
  <setAppendCarResponse 
    soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</soapenv:Body>

Fragt man dann mit CarStoreGetCarArray den Inhalt wieder ab, ergibt sich

gefundene Autos:
Auto[0] = Opel
Auto[1] = Porsche
Auto[2] = BMW
Auto[3] = Audi
Auto[4] = VW
Auto[5] = Mazda
Auto[6] = Toyota
Auto[7] = Volvo
Auto[8] = Renault

Statische Variablen bleiben also wie gewohnt bis zum Neuladen der Klasse erhalten. Um Informationen dauerhaft zu speichern müssen Datenbanken, Preferences oder Dateien verwendet werden.

Web Services Deployment Descriptor (WSDD)

Beispiel für den CarStore: CarStoreUnDeploy.wsdd.
Als Provider ist hier mit java:RPC die RPC-artige Durchführung gewählt.

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

<deployment name="test"
  xmlns="http://xml.apache.org/axis/wsdd/"
  xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" >

<service name="CarStore" 
         provider="java:RPC" >
  <parameter name="className" 
             value="CarStore"  />
  <parameter name="allowedMethods" 
             value="*" 
             value="getCar getCars setAppendCar getCarArray"  />
</service>
</deployment>

Die Aktivierung sieht z.B. wie folgt aus:

java ... org.apache.axis.client.AdminClient CarStoreDeploy.wsdd

Processing file CarStoreDeploy.wsdd
<Admin>Done processing</Admin>

Beispiel CarStoreUnDeploy.wsdd

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

<undeployment
  xmlns="http://xml.apache.org/axis/wsdd/"
  xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" >

<service name="CarStore" />

</undeployment>

Die Deaktivierung sieht z.B. wie folgt aus:

java ... org.apache.axis.client.AdminClient CarStoreUnDeploy.wsdd

Processing file CarStoreUnDeploy.wsdd
<Admin>Done processing</Admin>

Ausblick


© Universität Mannheim, Rechenzentrum, 2005-2006.

Heinz Kredel

Last modified: Fri Mar 31 21:37:07 CEST 2006