Minudika
Minudika

Reputation: 851

Extract numbers in correct format from a JSON string using Gson

I am trying to retrieve the elements from a JSON string using Gson. I want to get the numbers in correct type, but Gson gives integers as double values.

Here is my code:

String jsonString = "{'symbol':'WSO2','price':55.6,'volume':100}";
Object json = new Gson().fromJson(eventObject.toString(),Object.class);

How to parse the JSON string in order to get numbers in correct format?

Thanks!

Upvotes: 0

Views: 1469

Answers (2)

Lyubomyr Shaydariv
Lyubomyr Shaydariv

Reputation: 21105

JSON does not distinguish between numeric types defining a single numeric type only: number. This a clear ambiguity when you can consider a value of 100 as an integer, ... or a long, a double or a float depending on how you interpret it. See more at the following discussion from the other perspective: How to get value as java.lang.Object from Gson? : An excerpt of the JSON grammar:

  • value
    • string
    • number
    • object
    • array
    • true
    • false
    • null

where number is:

  • number
    • int
    • int frac
    • int exp
    • int frac exp

In Gson you cannot do it by deserializing to java.lang.Object because Gson, for this type, uses ObjectTypeAdapter which always parses a numeric value as a double, the biggest Java number JsonReader is designed for:

public final class ObjectTypeAdapter extends TypeAdapter<Object> {
...

    @Override public Object read(JsonReader in) throws IOException {
...
        case NUMBER:
            return in.nextDouble();
...

The most safe thing you can with it is just extracting the value and casting it to java.lang.Number (you might consider it as an "unknown" number) and use its methods like intValue(), longValue(), doubleValue() etc at the call site.

Upvotes: 1

Michael Sharp
Michael Sharp

Reputation: 496

So the first thing I would say is that you shouldn't be parsing json to an Object. Object can really be anything. You should do as JB Nizet suggested and define your own class with the types you want. Something like this.

public class ClassForJson {
    private String symbol;
    private double price;
    private int volume;

    public ClassForJson (String symbol, double price, int volume) {
        this.symbol = symbol;
        this.price = price;
        this.volume = volume;
    }

    public String getSymbol() {
        return symbol;
    }

    public double getPrice() {
        return price;
    }

    public int getVolume() {
        return volume;
    }

}

Gson will use the constructor to get the data in the class, and then you can use the getters to retrieve the data. Obviously you will want to rename the class to match what the data is representing. You should then change your previous code to something like this.

String jsonString = "{'symbol':'WSO2','price':55.6,'volume':100}";
ClassForJson jsonClass = new Gson().fromJson(jsonString,ClassForJson.class);

You can then access the data using the getters and they will be of the correct type.

Upvotes: 1

Related Questions