为什么wsimport在使用@XmlRootElement注释的服务器对象时遇到问题?

时间:2013-01-03 23:46:49

标签: java jaxb jax-ws xjc wsimport

我正在服务器端使用JAX-WS完成Web服务的工作。在许多域对象中,我使用@XmlRootElement来帮助促进使用JAXB将XML文件解组到服务中。一切顺利,输出就是我期望看到的使用SoapUI。

但是,当我使用wsimport创建客户端时(作为其他开发人员的便利DAO),我开始在客户端集成测试类中遇到NullPointerExceptions。

对webservice的调用工作正常,客户端收到响应,但我的更复杂的对象为null。简单的属性,如字符串,返回了大量可用数据,但不是更大的对象。

通过使用简单的字符串重新创建服务并迁移到更复杂的对象的迭代,我发现当客户端收到使用@XmlRootElement在服务器上声明的对象时,这些是null的对象。如果服务器对象没有@XmlRootElement注释,则客户端会收到所有复杂荣耀中的所有数据。

最初缺少@XmlRootElement让我适合解组服务器上的数据,但this answer帮助了我。

因此,由于@XmlRootElement注释(在服务器上!),wsimport客户端在解组Web服务响应时无声地失败的现象让我担心。在这种情况下,我控制了双方并且可以做些什么。但是,如果我无法控制服务器怎么办?我如何仅使用wsimport生成的代码解决这个问题?

1 个答案:

答案 0 :(得分:1)

找到答案或原因,以为我会分享。

@XmlRootElement注释对于普通JAXB绑定很有用,但是当对象(以及生成的XML)打包为SOAP响应时,它们可能并不完全相同匹配WSDL的数据表示,具体取决于其他注释的值。

使用@XmlRootElement方法返回的服务器上的类@WebMethod注释,WSDL将包含元素定义,例如:

<xs:element name="foo" type="tns:FooType"/>

然后在其他地方WSDL将包含对序列中元素的引用,例如:

<xs:seqeunce>
<xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:foo"/>
</xs:sequence>

这种引用是由@XmlRootElement注释引起的,可能会混淆根元素声明的意图与SOAP响应的实际XML相混淆。

相反,在服务器对象上没有WSDL注释的情况下生成的@XmlRootElement根本不包含<xs:element name="foo"/>声明。相反,它的元素被描述为:

<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="foo" type="tns:FooType"/>
</xs:sequence>

这可能更好地匹配SOAP响应XML的表示方式,并且将XML解组为wsimport生成的类的工作正常。

如何在@XmlRootElement服务中使用JAX-WS

wsimport似乎在处理服务返回的XML的有效性方面存在某种程度的懒惰。我们吸取的教训是,在nametargetNamespace上使用@WebResult注释来描述您的网络服务方法。 @XmlRootElement注释需要与name中的targetNamespace匹配。当它们全部匹配时,解组按预期发生。当这些值不匹配时,由wsimport生成和注释的存根类将无法正确使用XML。