# Webservice gibt das falsche aus - Wieso



## GetIT (12. Dez 2005)

Habe folgenden Webservice geschrieben:


```
package jwsMitAxis.bookstore;

public class Book
{
    private String title;
    private String author;
    
    public Book(String title, String author){
        this.title = title;
        this.author = author;
    }
    
    public String getTitle(){return title;}
    
    public void setTitle(String title){this.title = title;}
    
    public String getAuthor(){return author;}
    
    public void setAuthor(String author){this.author = author;}
}
```


```
package jwsMitAxis.bookstore;

public class Store
{
    private Book book = new Book("title", "author");
    
    public Book getBookDetails(){return book;}
}
```


```
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
				xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
				
	<service name="Bookstore" provider="java:RPC">
		<parameter name="className" value="jwsMitAxis.bookstore.Store"/>
		<parameter name="allowedMethods" value="*"/>		
		<typeMapping qname="myNS:Book" xmlns:myNS="http://bookstore.jwsMitAxis"
			languageSpecificType="java:jwsMitAxis.bookstore.Book"
			serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
			deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
			encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
	</service>
</deployment>
```

Diesen Webservice habe ich deployed und bekomme nach dem Aufruf von:


> localhost:8080/axis/services/Bookstore?method=getBookDetails


auch das richtige


> <soapenv:Envelope>
> -
> <soapenv:Body>
> -
> ...


zurück.


Jetzt hab ich mir nen Client dazu geschrieben:

```
package jwsMitAxis.bookstore;

import org.apache.axis.client.*;
import org.apache.axis.encoding.ser.*;

import java.net.URL;
import javax.xml.rpc.encoding.XMLType;
import javax.xml.rpc.ParameterMode;
import javax.xml.namespace.QName;

import jwsMitAxis.dvd.Movie;

public class StoreClient
{
    public static void main(String[] args)
    {
        try
        {
            String endpoint = "http://localhost:8080/axis/services/Bookstore";
            
            Service service = new Service();
            Call call = (Call)service.createCall();
            
            call.setTargetEndpointAddress(new URL(endpoint));
            
            call.setOperationName("getBookDetails");
            
            QName qnBook = new QName("http://bookstore.jwsMitAxis", "Book");
            
            call.registerTypeMapping(Book.class, qnBook, 
                    new BeanSerializerFactory(Book.class, qnBook),
                    new BeanDeserializerFactory(Book.class, qnBook));
            
            Book bookDetails = (Book)call.invoke(new Object[] {});
            
            System.out.println("Buch:\t" + bookDetails.getTitle());
            System.out.println("Author:\t" + bookDetails.getAuthor()); 
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
```

Dieser Client liefert mir die folgende Ausgabe:


> Buch:    author
> Author: author



Wieso??


 :bahnhof: 
Sorry, ich weiß das das weng viel Code auf einmal ist.
Aber wenn ich eine Chance haben will eine Antwort auf meine Frage zu bekommen muss das woll sein.


----------



## SnooP (12. Dez 2005)

was doch auch korrekt ist nach deinem Code...

die Soap-Nachricht liefert im Übrigen das Gleiche...

wenn du numal nen Buch definierst, was title und author als Strings speichert?


> ```
> private Book book = new Book("title", "author");
> ```


Ist das Ergebnis genau das, was ich erwarten würde


----------



## GetIT (13. Dez 2005)

> wenn du numal nen Buch definierst, was title und author als Strings speichert?


Hab ich doch


> private Book book = new Book("title", "author");


Also erwarte ich 


> Buch: title
> Author: author



Ich bekomme aber:


> Buch: author
> Author: author


----------



## SnooP (13. Dez 2005)

hoppa  - sorry - überlesen... hatte ich wohl Tomaten auf den Augen...

Dann versteh ichs auch nicht... kannst ja mal versuchen zu schauen, ob die soap-nachricht auch bei deinem client-aufruf so aussieht, wie sie aussehen soll indem du den tcpmon von axis dazwischenhängst...


----------



## Murray (13. Dez 2005)

Nur eine Vermutung, da ich nicht in den Axis-Code gesehen habe: möglicherweise erfordert der den BeanDeserializer einen Default-Konstruktor in der Book-Klasse; beim Deserialisieren muss ja zunächst einmal eine Instanz erzeugt werden, bevor dann mit den Settern die einzelnen Attribute gesetzt werden können. Eigentlich würde ich in so einem Fall eine Exception erwarten, aber möglicherweise versucht Axis hier, doch den einzigen verfügbaren Konstrukor zu verwenden und scheitert dabei an der Zuordnung der Parameter (woher soll Axis auch wissen, welche Semantik die beiden String-Argumente im Book-Konstruktor haben?).

Ergänze in Book doch mal einen Default-Konstruktor:

```
public Book() {
  this( "!!unknown title!!", "!!unknown author!!");
}
```

(Dabei ist die Delegation an der String-String-Konstruktur nicht wirklich nötig und im Produktivbetrieb auch möglicherweise störend, denn diese Zuweiseungen werden im Normalfall ja immer wieder überschreiben. Zum Debuggen  kann es aber ganz sinnvoll sein, einem Book-Objekt anzusehen, dass es auf diese Weise erzeugt und nicht wirklich vollständig initialisiert worden ist).


----------



## GetIT (13. Dez 2005)

Danke euch allen   

Der default Konstruktor hat gefehlt!! 

[schild=1 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]DANKE!!![/schild]


----------

