如何教 Apache CXF JAX-WS 客户端使用的 JAXB 解组未类型化 属性 中的 {http://microsoft.com/wsdl/types/}guid 值?

How to teach JAXB used by Apache CXF JAX-WS client to unmarshal {http://microsoft.com/wsdl/types/}guid values in an untyped property?

我有一个 SOAP 服务需要向其发送请求(特别是 Ivanti Integration Web Service)。

我使用 Apache CXF 3.2.7 连接到该服务。我使用 wsdl2java.

从服务的 WSDL 生成 Java 类

WSDL 没有提及任何 GUID,似乎完全自给自足。但是,有一个字段(名为 Value)是未类型化的,即。 e.没有 type 属性的 xsd:element,并且服务器在该字段中发送具有各种类型值的响应。它们看起来像这样:

字符串和短裤没问题,但 GUID 在客户端产生此异常:

javax.xml.bind.UnmarshalException: unrecognized type name: {http://microsoft.com/wsdl/types/}guid

我如何避免这个异常?我实际上并不关心这个字段的值,尽管实现类型安全解组的解决方案当然是理想。

我试过的

无论我做什么,异常都不会消失。特别是,我试过:

如果我理解正确(我一点也不确定),这个异常意味着 JAXB 没有为 GUID 类型注册的解组器,如果我能以某种方式获得支持,它应该被解决JAXB 注册表并添加我自己的编组器。但是在查看了 CXF 的 JavaDocs 之后,我不知道如何,甚至是否可以访问此注册表。有些方法听起来我可能可以获得 JAXBContext,但我看不出如何向已经存在的 JAXBContext 实例添加任何内容。

如果您将 wsdl2java 生成的源代码从您的原始 WSDL 导入您的源代码管理(并停止在每次构建时生成它们),您可以添加自定义 class 映射 simpleType:

import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;

@XmlType(namespace = "http://microsoft.com/wsdl/types/", name = "guid")
public class Guid {
   @XmlValue
   public String guid;
}

并向您的 wsdl2java 生成的 class 之一添加一个 @XmlSeeAlso(Guid.class) 注释,这些注释已经被 JAXB 拾取,例如。 G。实际服务 class。服务 class 可能已经有 @XmlSeeAlso({ObjectFactory.class}),因此您可以将其更改为 @XmlSeeAlso({ObjectFactory.class, Guid.class})

这样,JAXB 将成功地将 GUID 解组为具有纯字符串内容的 Guid 实例。如果你想要实际的 java.util.UUID 个实例,你可以在 @XmlValue 字段上添加 @XmlJavaTypeAdapter,但我还没有测试过这个。

(顺便说一句:当您尝试将 xsd:element 添加到 WSDL 时,我认为您添加了一个名为 XML 元素 的映射 guid,例如 <q2:guid xmlns:q2="http://microsoft.com/wsdl/types/">c3aca40a-439d-4af2-b42e-59b1ddcf3d6e</q2:guid>。这不是您想要的,所以这解释了为什么它没有帮助您。)