I\'m reading a JSON response with Gson, which returns somtimes a NumberFormatException
because an expected int
value is set to an empty string. Now
As stated in another comment, as of GSON 2.3.1 you can register type adapters for primitive types, here is a type adapter that handles int and Integer types, and gracefully defaults to 0 (or null) for strings, booleans and nulls. This will continue to parse strings that have numbers in them like "runtime" : "5".
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);
You can register it with the following code
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(UNRELIABLE_INTEGER_FACTORY)
.create();
Note that the normal JsonReader.nextInt() that this replaces attempts to call parseInt and parseDouble on the token, so this will replicate internal logic for parsing integers.