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

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

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

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

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

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

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

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

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

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

  

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

    

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

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

    

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

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

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