views:

185

answers:

1

I'm creating a web service in Java that will be consumed by an external application, probably written in C#. In my Purchase bean, I have a Currency object for the total cost. However, this leads to the following error:

Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.util.Currency does not have a no-arg default constructor.

I found a solution to create a custom XML Adapter to handle the Currency marshalling/unmarshalling:

public class CurrencyAdapter extends XmlAdapter<String,Currency> {
  public Currency unmarshal(String val) throws Exception {
    return Currency.getInstance(val);
  }
  public String marshal(Currency val) throws Exception {
    return val.toString();
  }
}

Could I use that custom XML Adapter, or use a BigDecimal (or other type) object to represent the cost?

+3  A: 

You are conflating a currency (which is a named unit) and a cost (which is some quantity in that unit). You can't represent a Currency as a BigInteger, because a Currency is not a quantity.

Jonathan Feinberg
I didn't understand what you meant until I was getting an illegal argument exception when trying to set the currency to a numeric value. Only then did I look at the javadoc and realize what you meant. Anyway, the question remains - what data type should I use to pass an actual cost quantity in a web service?
David Buckley
You should use any data type that represents, as an integer, the number of the smallest unit of currency. For example, in dollars, your quantity would be the number of *cents*, although some transactions requre tenths of cents, in which case your number (still an integer) would represent the number of tenths of a cent. As long as you don't use floating point, you'll be ok. Then you just have to pick a data type large enough to handle the maximum transaction size without overflow.
Jonathan Feinberg