java - 为什么 wsimport 在处理具有 @XmlRootElement 注释的服务器对象时遇到问题?

标签 java jaxb jax-ws xjc wsimport

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

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

对 Web 服务的调用工作正常,并且客户端收到了响应,但我的更复杂的对象为空。简单的属性(例如字符串)返回了完整的可用数据,但没有返回较大的对象。

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

最初,缺少 @XmlRootElement 让我无法在服务器上解码数据,但是 this answer帮我解决了。

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

最佳答案

找到答案或原因,所以我想分享。

@XmlRootElement注释对于普通 JAXB 很有用绑定(bind),但是当对象(以及生成的 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 生成的类中的方式。工作得很好。

如何使用@XmlRootElementJAX-WS服务?

wsimport似乎在处理服务返回的 XML 有效性方面存在某种程度的惰性。吸取的教训是要勤奋地使用nametargetNamespace在您的@WebResult上描述您的 Web 服务方法的注释。 @XmlRootElement注释需要匹配 name targetNamespace内。当它们全部匹配时,解码就会按预期发生。当这些值不匹配时,您的 stub 类将生成并由 wsimport 注释。将无法正确使用 XML。

关于java - 为什么 wsimport 在处理具有 @XmlRootElement 注释的服务器对象时遇到问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14149121/

相关文章:

java - 将文件 move 到其他位置

java - Sencha CMD 7 dockerfile失败,具有非法反射访问

java - 具有多个命名空间的 JXPath

java - Soap:如何验证空元素

java - 如何使用 JAXB 编写深度 XML 文档?

java - 如何在Java中正确使用方法结果

java - 为什么以及何时我们需要在 android 中创建内部类

java - 如何将 SOAP header 添加到 Spring Jax-WS 客户端?

java - 为使用 JAX-WS 的初始 WSDL 检索指定超时?

java - JAX-WS,身份验证和授权 - 如何?