11

The WSDL file I used to create the CXF client has this element definition:

<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>

However when I try to send the SOAP message, number of digits in after decimal point exceeds the maximum value. For example I get 2.48862 while expecting 2.48. In order to solve this I was planning to implement a XmlAdapter to marshall the values, however I cannot map the element in WSDL to the client because onyl class of XmlAdapter is passed to field decleration as annotation.

@XmlJavaTypeAdapter(CustomXmlAdapter.class)

There seems to be no way to inform the XmlAdapter that field must have 2 digits after decimal point.

The number of fraction digits changes from element to element. I also don't have the access to change the WSDL.

Is there a way to format these elements while observing the number of decimal points specified in the WSDL?

regulus
  • 1,572
  • 12
  • 18
  • 2
    Have you already had a look at [this SO post](http://stackoverflow.com/questions/14848776/jaxb-marshalling-for-bigdecimal-using-fractiondigits)? It seems to tackle a similar problem. – Roman Vottner Dec 29 '13 at 14:43
  • Yes I've seen it before I've already posted. It requires me to create a different class for each different number of fractions. – regulus Jan 02 '14 at 20:51
  • What is best for you, depends on your particular use case. Are you dealing with multi-currency financial software, where transaction amounts in different currencies may require different precisions? Then you may want to look for a more flexible framework than this. On the other hand, if each entity/property has its own *fixed* precision, then you should take for granted that you may have to implement a separate class for each individual entity/property. Just how many flavors of precision can there be? If you are worried about code duplication, then hopefully class inheritance can be of help. – Ruud Helderman Jan 03 '14 at 22:49
  • @Ruud the problem is precisions change on the type of the system whether it's the production or test system. And there is always the possibility that the WSDL can change. – regulus Jan 03 '14 at 23:32
  • You may want to maintain your metadata (including precisions) separately; stored and published in any way you find convenient (XML file, database, web service...). Use this metadata as a single source of information for both the WSDL file and the XmlAdapter. The adapter simply reads the metadata to behave accordingly. As for the WSDL file, that depends; who is responsible for maintaining the WSDL file, do you have any influence on that? If you have, then you could generate the WSDL file from the metadata. Otherwise, you could try the reverse: generate metadata based on the appropriate WSDL. – Ruud Helderman Jan 04 '14 at 09:08
  • Another line of thought - if your WSDL/XSD had a restriction on a String element such as max-length, does your generated code checks the string length? Not as far as I know. At least not by CXF. So I wouldn't expect it to do so for decimal numbers. So the idea of a different framework sounds good, or some data-mapper (such as dozzer) or apply changes on the generated code. – OmegaZiv Jan 05 '14 at 06:24
  • You could look at JAXB facets libraries https://github.com/whummer/jaxb-facets – Konstantin V. Salikhov Jan 16 '14 at 12:49

1 Answers1

1

I might suggest the use of xQuery on the schema referenced by the WSDL. The name and location of the schema are part of the WSDL, and can be retrieved via XQuery also.

Schemas are well-formed XML, so you will just have to determine the correct XPath selector to retrieve the desired value - in this case, that will be at a minimum something like...

//xsd:element[@name == 'Rate']//xsd:fractionDigits/@value

Which should yield the value 2.

Keep in mind that there is an XPath/XQuery interpretor built into the latest JDKs. You merely have to put some kind of front-end on it, and I believe it will handle streams quite nicely.

Doing the above will let you query the schema dynamically as you are processing a given element, allowing you, for example, to get the correct number of decimal digits when processing the Rate.

Rodney P. Barbati
  • 1,883
  • 24
  • 18