2011-02-09 9 views
9

ho questo semplice JAX-WS WebService:Utilizzando polimorfico webservice JAX-WS parametri

@WebService 
public class AnimalFeedingService { 
    @WebMethod 
    public void feed(@WebParam(name = "animal") Animal animal) { 
     // Whatever 
    } 
} 

@XmlSeeAlso({ Dog.class, Cat.class }) 
public abstract class Animal { 
    private double weight; 
    private String name; 
    // Also getters and setters 
} 

public class Dog extends Animal {} 

public class Cat extends Animal {} 

ho creare un client e chiamare feed con un'istanza di Dog.

Animal myDog = new Dog(); 
myDog .setName("Rambo"); 
myDog .setWeight(15); 
feedingServicePort.feed(myDog); 

L'animale nel corpo della chiamata SOAP assomiglia a questo:

<animal> 
    <name>Rambo</name> 
    <weight>15</weight> 
</animal> 

e ottengo una UnmarshallException perché Animal è astratta.

C'è un modo per avere Rambo unmarshalled come istanza di classe Dog? Quali sono le mie alternative?

risposta

6

Come si può intuire, il parser XML non è in grado di determinare il sottotipo esatto dell'animale utilizzato durante la richiesta perché tutto ciò che vede è generico <animal> e un insieme di tag comuni a tutti i tipi, quindi l'errore. Quale implementazione JAX-WS usi? È responsabilità del cliente avvolgere correttamente i tipi polimorfici durante l'invio della richiesta. In Apache CXF (ho controllato il codice contro nuova versione 2.3.2) la richiesta corpo SOAP si presenta così:

<animal xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:dog"> 
    <name>Rambo</name> 
    <weight>15.0</weight> 
</animal> 

Il xsi:type="ns2:dog" è fondamentale qui. Sembra che il tuo client JAX-WS stia inviando una richiesta errata che confonde il server. Prova a inviare questa richiesta con altri client, come SoapUI, per vedere se il tuo server reagisce correttamente.

Come ho già detto, funziona bene con la Primavera/Apache CXF ed esattamente lo stesso codice che hai fornito, io interfaccia Java solo estratto di fare CXF felice:

public interface AnimalFeedingService { 

    @WebMethod 
    void feed(@WebParam(name = "animal") Animal animal); 

} 

@WebService 
@Service 
public class AnimalFeedingServiceImpl implements AnimalFeedingService { 
    @Override 
    @WebMethod 
    public void feed(@WebParam(name = "animal") Animal animal) { 
     // Whatever 
    } 
} 

... e il server/codice colla cliente:

<jaxws:endpoint implementor="#animalFeedingService" address="/animal"/> 

<jaxws:client id="animalFeedingServiceClient" 
       serviceClass="com.blogspot.nurkiewicz.test.jaxws.AnimalFeedingService" 
       address="http://localhost:8080/test/animal"> 
</jaxws:client> 
+0

Utilizzando xsi: digitare da SoapUI ha funzionato, il problema deve essere nel mio client. Grazie. – adrianboimvaser

Problemi correlati