CXF客户端SOAP消息格式化

11

我用来创建CXF客户端的WSDL文件具有以下元素定义:

<xsd:element name="Rate"> 
  <xsd:simpleType>
    <xsd:restriction base="xsd:decimal">
      <xsd:totalDigits value="18" />
      <xsd:fractionDigits value="2" />
    </xsd:restriction>
  </xsd:simpleType>
</xsd:element>

然而,当我尝试发送SOAP消息时,小数点后的位数超过了最大值。例如,我得到了2.48862,而期望的是2.48。为了解决这个问题,我打算实现一个XmlAdapter来编组这些值,但我无法将WSDL中的元素映射到客户端,因为只有XmlAdapter类作为注释传递给字段声明。

@XmlJavaTypeAdapter(CustomXmlAdapter.class)

似乎没有办法告诉XmlAdapter字段必须在小数点后有2位数字。

小数位数从元素到元素不同。我也无法更改WSDL。

是否有一种方式可以在遵守WSDL中指定的小数点位数的同时格式化这些元素?


2
你是否已经看过这篇SO帖子?它似乎解决了类似的问题。 - Roman Vottner
什么对你最好,取决于你的特定用例。你是否处理多货币金融软件,其中不同货币的交易金额可能需要不同的精度?那么你可能想寻找比这更灵活的框架。另一方面,如果每个实体/属性都有自己的固定精度,那么你应该认为你可能必须为每个单独的实体/属性实现一个单独的类。有多少种精度可以有呢?如果你担心代码重复,那么希望类继承能够提供帮助。 - Ruud Helderman
您可能希望单独维护元数据(包括精度),并以任何方便的方式进行存储和发布(如XML文件,数据库,Web服务等)。将此元数据用作WSDL文件和XmlAdapter的唯一信息来源。适配器只需读取元数据即可相应地行事。至于WSDL文件,则取决于谁负责维护WSDL文件,您对此有任何影响吗?如果是的话,您可以从元数据中生成WSDL文件。否则,您可以尝试反向操作:根据适当的WSDL生成元数据。 - Ruud Helderman
另一种思路 - 如果您的WSDL / XSD对字符串元素(例如max-length)有限制,那么您生成的代码是否检查字符串长度?据我所知,CXF并不会这样做。至少不会针对十进制数。因此,使用不同的框架或某些数据映射器(例如dozzer)或对生成的代码进行更改的想法听起来不错。 - OmegaZiv
你可以查看JAXB Facets库 https://github.com/whummer/jaxb-facets - Konstantin V. Salikhov
显示剩余2条评论
1个回答

1
我建议在WSDL引用的模式上使用xQuery。 模式的名称和位置是WSDL的一部分,并且也可以通过XQuery检索到。
模式是格式良好的XML,因此您只需确定正确的XPath选择器以检索所需的值 - 在本例中,至少将是以下内容...
//xsd:element[@name == 'Rate']//xsd:fractionDigits/@value

这应该会产生值为2。

请注意,最新的JDK中内置了XPath/XQuery解释器。 您只需在其上添加某种前端界面,我相信它将非常好地处理流。

执行以上操作将使您能够在处理给定元素时动态查询模式,例如,在处理汇率(Rate)时获取正确的小数位数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接