henriqueolliveira / google-api-java-client

Automatically exported from code.google.com/p/google-api-java-client
0 stars 0 forks source link

map empty XML attribute to null #178

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
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.

<response rate="" />

Partial stacktrace:

java.lang.NumberFormatException
    at java.math.BigDecimal.<init>(BigDecimal.java:457)
    at java.math.BigDecimal.<init>(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.

Original issue reported on code.google.com by tra...@circutus.com on 13 Apr 2011 at 9:12

GoogleCodeExporter commented 9 years ago
Good question.

The only problem I see with setting it to null is that if you later serialize 
the XML you would get:

<response/>

Another option is to set it to 0, but again on serialization you get:

<response rate="0" />

An annotation like @AllowEmptyXMLAttribtue would mean that then there is no way 
to say that this attribute is missing, so if we see this:

<response/>

We will serialize it as:

<response rate="" />

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?

Original comment by yan...@google.com on 13 Apr 2011 at 10:04

GoogleCodeExporter commented 9 years ago
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 comment by tra...@circutus.com on 19 Apr 2011 at 3:31

GoogleCodeExporter commented 9 years ago
Moved to:
http://code.google.com/p/google-http-java-client/issues/detail?id=5

Original comment by yan...@google.com on 11 May 2011 at 5:03