next up previous
Nächste Seite: Fazit Aufwärts: XML-basierte Kommunikation mit SOAP Vorherige Seite: Quelltexte

Objekte

Wenn man das Object verwendet wird es etwas weniger Simple. Das Problem bei eigenen Objekten ist, daß sie serialisiert werden mussen.

Auf der Serverseite gibt es Programmteschnisch keinen großen Unterschied:

package demoobj;       

public class Service {
    public String showObject(MyObject obj) {
        return "Name: " + obj.getName() + " Number: " + obj.getNumber();
    }
}

Beim deployen des Services müssen zusätzlich Infrmationen über die vom Client verwendete Art der Serialisierung gemacht werden. Das geht Entweder über das bekannte Webfrontend, oder über eine passende DeploymentDescriptor.xml Datei.

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" 
  id="urn:demoobj">
  <isd:provider type="java" scope="Application" methods="showObject">
    <isd:java class="demoobj.Service" static="false"/>
  </isd:provider>
  <isd:mappings>
    <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:x="urn:demoobj" qname="x:demoobj.MyObject"
        javaType="demoobj.MyObject"
        java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"
        xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/>
  </isd:mappings>
</isd:service>

Einmal die Daten wie gehabt. Zusätzlich wird das Objekt bekannt gemacht. Das Objekt muß natürlich vorhanden sein. Das erledigt diese Klasse:

package demoobj;

public class MyObject
{
    private String name;
    private int number;

    public String getName() {
        return name;
    }
    
    public int getNumber() {
        return number;
    }
    
    public void setName(String name) {
        this.name=name;
    }
    
    public void setNumber(int number) {
        this.number=number;
    }
}

Beim Client gibt es jetzt etwas mehr zu tun:

package demoobj;       
import java.net.URL;
import java.util.Vector;
import org.apache.soap.SOAPException;
import org.apache.soap.Constants;
import org.apache.soap.Fault;
import org.apache.soap.rpc.Call;
import org.apache.soap.rpc.Parameter;
import org.apache.soap.rpc.Response;

import org.apache.soap.encoding.SOAPMappingRegistry;
import org.apache.soap.encoding.soapenc.BeanSerializer;
import org.apache.soap.util.xml.QName;

public class Client {
    public static void main(String[] args) {
    MyObject obj = new MyObject();    
    URL url;
    if(args.length != 1) {  //stimmt die Zahl der Argumente?
        System.err.println("Aufruf: java demoobj.Client \
            [SOAP-router-URL]");
        System.exit(1);
    }    
    try {
        url = new URL(args[0]);
       
        obj.setName("Beispielprogramm");
        obj.setNumber(3); 
        
        //den Aufruf vorbereiten
        Call call = new Call();
        call.setTargetObjectURI("urn:demoobj"); //ID des aufzurufenden 
                                                //Services   
        call.setMethodName("showObject"); //Name der Prozedur
        call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); //standard SOAP Codierung

        // type mapping registry erzeugen
        SOAPMappingRegistry smr = new SOAPMappingRegistry();
        BeanSerializer beanSer = new BeanSerializer();
        // Typen mappen
        smr.mapTypes(Constants.NS_URI_SOAP_ENC,
                new QName("urn:demoobj", "demoobj.MyObject"), \
                            demoobj.MyObject.class, beanSer, beanSer);
        // Mapping anwenden
        call.setSOAPMappingRegistry(smr);
        
        Vector myParameter = new Vector();
        myParameter.addElement(new Parameter("obj", MyObject.class, \
             obj, null));
        call.setParams(myParameter);

        //der Aufruf
        Response resp = null;
        try {
            resp = call.invoke(url, "");
        }
        catch( SOAPException e )
        {
            System.err.println("SOAP Exception (" + e.getFaultCode() \
                + "): " + e.getMessage());
            System.exit(1);
        }

        //Ergebniss auswerten
        if( !resp.generatedFault()) {
            Parameter ret = resp.getReturnValue();
            Object value = ret.getValue();
            System.out.println(value);
        }
        else {
            Fault fault = resp.getFault();
            System.err.println("zurückgelieferter Fehler:");
            System.err.println (" Fault Code = " + fault.getFaultCode());
            System.err.println (" Fault String = " + fault.getFaultString()); 
        }
       }
         catch(Exception e) {
            System.err.println("Sonstige Exception");
            e.printStackTrace();
        }
     }
    
}

Im großen und ganzen sieht der Client aus wie im vorherigen Beispiel, nur wird jetzt eine Objekt einer selbstdefinierte Klasse übergeben. Dazu muß eine Serialisierungsvorschrift ausgewählt werden.

Der Aufruf liefert diese Ausgabe:

$ java demoobj/Client http://localhost:8080/soap/servlet/rpcrouter
Name: Beispielprogramm Number: 3
$

Um das zu ermöglichen schickt der Client folgende Anfrage an den Server:

POST /soap/rpcrouter HTTP/1.0
Host: greg.local
Content-Type: text/xml; charset=utf-8
Content-Length: 533
SOAPAction: ""

<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/1999/XMLSchema">
   <SOAP-ENV:Body>
     <ns1:showObject xmlns:ns1="urn:demoobj"
       SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
       <obj xsi:type="ns1:demoobj.MyObject">
         <name xsi:type="xsd:string">Beispielprogramm</name>
         <number xsi:type="xsd:int">3</number>
       </obj>
     </ns1:showObject>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Der Server schickt als Antwort:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 487
Date: Mon, 21 Jan 2002 19:58:53 GMT
Server: Apache Tomcat/4.0.1 (HTTP/1.1 Connector)
Set-Cookie: JSESSIONID=A177B88412F481C470B1F040E7D49367;Path=/soap

<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/1999/XMLSchema">
  <SOAP-ENV:Body>
    <ns1:showObjectResponse xmlns:ns1="urn:demoobj"
     SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
     <return xsi:type="xsd:string">Name: Beispielprogramm Number: 3</return>
   </ns1:showObjectResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>



Wolfgang Becker 2002-01-22