Created
September 5, 2015 08:10
-
-
Save tamast/ad468b517adcf4dc259c to your computer and use it in GitHub Desktop.
Gson NumberFormatException for empty string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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