Gson: JsonParseException when encountering an empty value for an int or long

Created on 19 Mar 2015  路  5Comments  路  Source: google/gson

What steps will reproduce the problem?
1. Create a data class with an int data member and a default value of 0 (any 
value would do).  Example:
public class GsonData {
    public int intValue = 0;
}

2. Create a json document with an empty value for intValue.  Example:
{
    "intValue":""
}
3. Parse the document:
String jsonString = < the json file as a string >
GsonData testDoc = new Gson().fromJson(jsonString, GsonData.class);

What is the expected output? 
I would expect that the document would parse correctly and result in intValue 
having the default value of 0.

What do you see instead?
It throws a parse exception because the empty value could not be converted to 
an int.

com.google.gson.JsonParseException: The JsonDeserializer IntegerTypeAdapter 
failed to deserialized json object "" given the type int

What version of the product are you using? 
gson-1.5.jar

On what operating system?
Windows 2008 R2

Please provide any additional information below.

Original issue reported on code.google.com by [email protected] on 17 Sep 2012 at 4:00

Most helpful comment

I know this bug is closed but it's one of the top google results when searching for this issue so I wanted to provide a broader solution to what was posted above, since it only attempts to handle empty strings

This code below will continue to correctly parse json tokens that look like ints, doubles, and strings ints and string doubles, while defaulting to 0 (or null for Integer types) on nulls, empty strings, invalid strings, and boolean values

public static final TypeAdapter<Number> UNRELIABLE_INTEGER = new TypeAdapter<Number>() {
    @Override
    public Number read(JsonReader in) throws IOException {
        JsonToken jsonToken = in.peek();
        switch (jsonToken) {
            case NUMBER:
            case STRING:
                String s = in.nextString();
                try {
                    return Integer.parseInt(s);
                } catch (NumberFormatException ignored) {
                }
                try {
                    return (int)Double.parseDouble(s);
                } catch (NumberFormatException ignored) {
                }
                return null;
            case NULL:
                in.nextNull();
                return null;
            case BOOLEAN:
                in.nextBoolean();
                return null;
            default:
                throw new JsonSyntaxException("Expecting number, got: " + jsonToken);
        }
    }
    @Override
    public void write(JsonWriter out, Number value) throws IOException {
        out.value(value);
    }
};
public static final TypeAdapterFactory UNRELIABLE_INTEGER_FACTORY = TypeAdapters.newFactory(int.class, Integer.class, UNRELIABLE_INTEGER);

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(UNRELIABLE_INTEGER_FACTORY)
    .create();

All 5 comments

This solution posted here worked for me: 
https://groups.google.com/forum/#!msg/google-gson/kNf5HADtY14/bdD1xmDPbH0J

I created a new class as follows:

public class IntTypeAdapter extends TypeAdapter<Number> {

    @Override
    public void write(JsonWriter out, Number value)
            throws IOException {
        out.value(value);
    }

    @Override
    public Number read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }
        try {
            String result = in.nextString();
            if ("".equals(result)) {
                return null;
            }
            return Integer.parseInt(result);
        } catch (NumberFormatException e) {
            throw new JsonSyntaxException(e);
        }
    }
}


And then ran the gson parsing as follows:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(int.class, new IntTypeAdapter())
    .registerTypeAdapter(Integer.class, new IntTypeAdapter()).create();
myObject = gson.fromJson(myJsonString, Student.class);


Original comment by [email protected] on 25 Sep 2012 at 7:08

Working as intended.

Original comment by limpbizkit on 4 Feb 2013 at 4:09

  • Changed state: WontFix

@GoogleCodeExporter Why won't this issue be fixed? Isn't this considered as a bug?

@GokhanArik it is not logical to parse "" empty string as 0 integer

I know this bug is closed but it's one of the top google results when searching for this issue so I wanted to provide a broader solution to what was posted above, since it only attempts to handle empty strings

This code below will continue to correctly parse json tokens that look like ints, doubles, and strings ints and string doubles, while defaulting to 0 (or null for Integer types) on nulls, empty strings, invalid strings, and boolean values

public static final TypeAdapter<Number> UNRELIABLE_INTEGER = new TypeAdapter<Number>() {
    @Override
    public Number read(JsonReader in) throws IOException {
        JsonToken jsonToken = in.peek();
        switch (jsonToken) {
            case NUMBER:
            case STRING:
                String s = in.nextString();
                try {
                    return Integer.parseInt(s);
                } catch (NumberFormatException ignored) {
                }
                try {
                    return (int)Double.parseDouble(s);
                } catch (NumberFormatException ignored) {
                }
                return null;
            case NULL:
                in.nextNull();
                return null;
            case BOOLEAN:
                in.nextBoolean();
                return null;
            default:
                throw new JsonSyntaxException("Expecting number, got: " + jsonToken);
        }
    }
    @Override
    public void write(JsonWriter out, Number value) throws IOException {
        out.value(value);
    }
};
public static final TypeAdapterFactory UNRELIABLE_INTEGER_FACTORY = TypeAdapters.newFactory(int.class, Integer.class, UNRELIABLE_INTEGER);

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(UNRELIABLE_INTEGER_FACTORY)
    .create();
Was this page helpful?
0 / 5 - 0 ratings

Related issues

GoogleCodeExporter picture GoogleCodeExporter  路  14Comments

GoogleCodeExporter picture GoogleCodeExporter  路  15Comments

kramer picture kramer  路  26Comments

GoogleCodeExporter picture GoogleCodeExporter  路  16Comments

danieleguiducci picture danieleguiducci  路  34Comments