Skip to content

Instantly share code, notes, and snippets.

@tamast
Created September 5, 2015 08:10
Show Gist options
  • Save tamast/ad468b517adcf4dc259c to your computer and use it in GitHub Desktop.
Save tamast/ad468b517adcf4dc259c to your computer and use it in GitHub Desktop.
Gson NumberFormatException for empty string
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.apache.commons.lang.math.NumberUtils;
import java.io.IOException;
public class GsonEmptyStringDemo {
/*
*
* Gson throws NumberFormatException when the json string contains an empty string value and the key belongs to a numeric field.
*
* "" -> int : NumberFormatException
* "" -> Integer : NumberFormatException
* "" -> int or Integer using TypeAdapter handles empty string : Works
* "" -> String : Works
*
* */
public static void main(String[] args) {
/*Test test = new Test();
test.setA(1);
test.setB(2);
Gson gson = new Gson();
String json = gson.toJson(test);
System.out.println(json);*/
deserializeEmptyStringToPrimitive();
deserializeEmptyStringToInteger();
deserializeEmptyStringToString();
deserializeEmptyStringWithTypeAdapter();
}
private static void deserializeEmptyStringToPrimitive() {
System.out.println("Try to map empty String to int");
try {
Gson gson =
new GsonBuilder()
.create();
Test1 t = gson.fromJson("{\"a\":\"\",\"b\":2.0}", Test1.class);
System.out.println(t);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("----------------------------------------");
}
private static void deserializeEmptyStringToInteger() {
System.out.println("Try to map empty String to Integer");
try {
Gson gson =
new GsonBuilder()
.create();
Test2 t = gson.fromJson("{\"a\":\"\",\"b\":2.0}", Test2.class);
System.out.println(t);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("----------------------------------------");
}
private static void deserializeEmptyStringToString() {
System.out.println("Using String type to handle Empty String");
try {
Gson gson =
new GsonBuilder()
.create();
Test t = gson.fromJson("{\"a\":\"\",\"b\":2.0}", Test.class);
System.out.println(t);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("----------------------------------------");
}
private static void deserializeEmptyStringWithTypeAdapter() {
System.out.println("Using TypeAdapter to handle Empty String");
try {
Gson gson =
new GsonBuilder()
.registerTypeAdapter(int.class, new EmptyStringToNumberTypeAdapter())
.registerTypeAdapter(Integer.class, new EmptyStringToNumberTypeAdapter())
.registerTypeAdapter(double.class, new EmptyStringToNumberTypeAdapter())
.registerTypeAdapter(Double.class, new EmptyStringToNumberTypeAdapter())
.create();
Test1 t = gson.fromJson("{\"a\":\"\",\"b\":\"\"}", Test1.class);
System.out.println(t);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("----------------------------------------");
}
public static class Test {
//String solves the problem
private String a;
private double b;
public int getA() {
if(a == null || a.equals("")){
return 0;
}
return Integer.valueOf(a);
}
public void setA(String a) {
this.a = a;
}
public double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
@Override
public String toString() {
return "Test{" +
"a=" + a +
", b=" + b +
'}';
}
}
public static class Test2 {
private Integer a;
private double b;
//Integer: empty string still causes NumberFormatException
public Integer getA() {
return a;
}
public void setA(Integer a) {
this.a = a;
}
public double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
@Override
public String toString() {
return "Test{" +
"a=" + a +
", b=" + b +
'}';
}
}
public static class Test1 {
private int a;
private double b;
//int: empty string causes NumberFormatException
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
@Override
public String toString() {
return "Test{" +
"a=" + a +
", b=" + b +
'}';
}
}
public static class EmptyStringToNumberTypeAdapter extends TypeAdapter<Number> {
@Override
public void write(JsonWriter jsonWriter, Number number) throws IOException {
if (number == null) {
jsonWriter.nullValue();
return;
}
jsonWriter.value(number);
}
@Override
public Number read(JsonReader jsonReader) throws IOException {
if (jsonReader.peek() == JsonToken.NULL) {
jsonReader.nextNull();
return null;
}
try {
String value = jsonReader.nextString();
if ("".equals(value)) {
return 0;
}
return NumberUtils.createNumber(value);
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment