我有这个简单的JAX-WS WebService:
@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 {}
我创建了一个客户端,并使用feed
的实例调用Dog
。
Animal myDog = new Dog();
myDog .setName("Rambo");
myDog .setWeight(15);
feedingServicePort.feed(myDog);
SOAP调用主体中的动物如下所示:
<animal>
<name>Rambo</name>
<weight>15</weight>
</animal>
我得到UnmarshallException
,因为Animal
是抽象的。
有没有办法让Rambo作为类Dog
的实例解组?我有什么选择?
答案 0 :(得分:7)
正如您可能已经猜到的那样,XML解析器无法确定您在请求时使用的动物的确切子类型,因为它看到的任何东西都是通用的<animal>
和一组对所有类型都通用的标记,因此错误。您使用什么JAX-WS实现?客户端有责任在发送请求时正确包装多态类型。在Apache CXF(我根据最新的2.3.2版本检查了你的代码),SOAP请求体看起来像这样:
<animal xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:dog">
<name>Rambo</name>
<weight>15.0</weight>
</animal>
xsi:type="ns2:dog"
在这里至关重要。看起来您的JAX-WS客户端发送的错误请求会混淆服务器。尝试与其他客户端(如SoapUI)一起发送此请求,以查看您的服务器是否做出了正确的反应。
正如我所说,它与Spring / Apache CXF完全一致并且与您提供的代码完全相同,我只提取Java接口以使CXF满意:
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
}
}
...和服务器/客户端粘合代码:
<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>