【发布时间】:2019-10-29 05:25:28
【问题描述】:
我正在尝试为在工作中调用 Web 服务的 Java 应用程序添加一些前向兼容性,但 JAXB 似乎在该主题上表现落后...
应用程序使用wsdl2java Maven 插件从 WSDL 生成 CXF Web 服务客户端。然后,它使用生成的客户端与 Web 服务进行通信(通过 JMS 上的 SOAP)。
当 Web 服务在其对调用的响应中发送未知元素时,JAXB 会失败并出现“意外元素”错误,这是可以理解且符合 XML 的。为了更加向前兼容,我指定了一个自定义 jaxb-reader-validation-event-handler 来忽略这些特定错误,从而解决了问题。
但在进行一些补充测试时,我发现了不符合 XML 的行为。
首先,JAXB 不关心元素的顺序,即使在 sequence 内部也是如此,这不是 XML 兼容的,但有利于向前兼容,所以为什么不呢。
但是,它也不关心强制元素 (minOccurs="1") 是否不存在,而是为它分配一个任意默认值(即,对于绑定到 Java 原始值的元素,它们的默认值,如 @987654325 的 0 @!)。
这既不符合 XML 并且 也不利于兼容性:如果您需要一个强制性的,例如,作为整数的价格,但由于某种原因 Web 服务没有提供它,JAXB 分配将其设为 0 而不会发出警告,这使得调试非常困难。
显然这是因为如果 JAXB 没有遇到一个元素,它根本不会调用它的 setter,这意味着它将保持其默认值。
[编辑:我做了一些补充测试,当应用程序需要 1 个元素 (maxOccurs="1") 但 Web 服务发送 2 时,JAXB 调用相同的设置器两次,用第二个值覆盖第一个值,所以似乎一旦客户端是从 WSDL 生成的,minOccurs 和 maxOccurs 被简单地忽略...]
如果缺少强制元素,如何使 JAXB 失败?
我们注意到,即使是带有minOccurs="1" 的元素,对应的生成属性的注解也不包含required = true。我尝试在生成之后和启动应用程序之前手动添加它,但没有成功:似乎它只是被忽略了......
【问题讨论】:
-
JAXB 不会为您进行任何验证,并且对于格式错误的 xml 消费具有相当 宽松 的行为。如果您希望您的 XML 得到验证,您必须在您的 un-marshaller 中注册一个模式。这将启用 JAXP 模式验证。
-
感谢您的提示!我查看了它,发现 JAX-WS 属性“schema-validation-enabled”似乎有效。您是否知道是否有任何其他验证方式(知道我没有手动进行(取消)编组,既不是针对 WSDL 也不是针对 SOAP)?
标签: xsd jaxb cxf wsdl2java fail-fast