From [email protected] on May 11, 2011 10:02:57
Copied from: https://code.google.com/p/google-api-java-client/issues/detail?id=178 Reported by [email protected], Apr 13, 2011
I have a class that maps an XML attribue to a BigDecimal.
public class SalesTaxRate
{
@key("@Rate")
public BigDecimal totalRate;
}
I don't have any control over the web service that I'm calling, but I noticed that they sometimes send an empty attribute value for "rate" and when google-api-java-client tries to map the empty string to a BigDecimal, a NumberFormatException is thrown.
Partial stacktrace:
java.lang.NumberFormatException
at java.math.BigDecimal.(BigDecimal.java:457)
at java.math.BigDecimal.(BigDecimal.java:647)
at com.google.api.client.util.FieldInfo.parsePrimitiveValue(FieldInfo.java:240)...
Is there a way around this problem without resorting to using String instead of BigDecimal?
If not, I would like to request that empty attribute values be mapped to null, as though the attribute wasn't present at all. Perhaps there could be an annotation to achieve this, if this could not be a global behavior.
Comment 1 by project member [email protected], Apr 13, 2011
Good question.
The only problem I see with setting it to null is that if you later serialize the XML you would get:
Another option is to set it to 0, but again on serialization you get:
An annotation like @AllowEmptyXMLAttribtue would mean that then there is no way to say that this attribute is missing, so if we see this:
We will serialize it as:
On the other hand, String deals with all of these cases correctly, but it requires you to then convert to/from BigDecimal everywhere in your application.
So it seems like no option is really ideal, though I tend to think just setting it null might be the most practical option.
By the way, in the case of the web service you are using, how are you supposed to interpret rate=""? Does it mean that the rate is 0, or that the rate is not known? Do you know why they return rate="" instead of the more straight-forward choices?
Comment 2 by [email protected], Apr 19, 2011
Thanks for the response. The key issue here for me is that right now, the way it works, deserialization can break for an empty XML attribute. I think that no matter what a long term solution is, a short term solution should be provided so that the NumberFormatException is not thrown, and the BigDecimal (or other objects like BigInteger) are deserialized to null.
For a long term solution, we should probably think in terms of how XML schemas (or similar mechanisms) define attributes as either "required" or "optional". There could be an annotation specifying whether or not an attribute is "required" explicitly, so that a required attribute that is null will be serialized to an empty attribute value. For the case of BigDecimal, you would still need to deserialize to null, even if the XML attribute is empty.
It wouldn't be easy to determine that the original attribute was empty in the first place. I guess you could have an annotation that defines a value to set the BigDecimal to when the original attribute is empty (e.g., set to minimum possible BigDecimal value). To be honest, I'm not sure it is worth it.
To answer your last few questions, the web service interprets rate="" as meaning that they can not determine the rate. I think it's just a bad design decision on their part (and probably too late to change for them, because I'm sure thousands of applications already use their web service).
Original issue: http://code.google.com/p/google-http-java-client/issues/detail?id=5