Gson parses an exception to an empty string
- 2020-05-16 06:58:08
- OfStack
preface
In a real development project, the server would often return an empty value with the empty string "" as the result, but this is problematic in Gson, where if the data type is not a string, Gson parsing would report an error
Json abnormal condition
Let's take a look at one of the background returns, json
Normally json:
{
"code":0,
"msg":"ok",
"data":{
"id":5638,
"newsId":5638
}
}
The entity class corresponding to data part:
public class JsonBean {
private int id;
private int newsId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getNewsId() {
return newsId;
}
public void setNewsId(int newsId) {
this.newsId = newsId;
}
}
Exception json(background database newsId field did not query the corresponding data):
{
"code":0,
"msg":"ok",
"data":{
"id":5638,
"newsId":""
}
}
So when Gson parses, it throws an exception with a parse error, and app crashes because it cannot convert "" to int
Exception handling for json
We expect that when the json exception is returned in the background, it can also be resolved successfully, and the corresponding null value is converted to the default value, such as:
newsId=0;
This excludes the background developer output when you do the correction, or have to rely on their own ah
Let's write a type converter for the int value that needs to implement Gson
JsonSerializer<T>
The interface and
JsonDeserializer<T>
The serialization and deserialization interfaces
public class IntegerDefault0Adapter implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
@Override
public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
if (json.getAsString().equals("") || json.getAsString().equals("null")) {// Is defined as int type , If the background comes back "" or null, It returns 0
return 0;
}
} catch (Exception ignore) {
}
try {
return json.getAsInt();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
The same goes for Long and Double types
double= >
public class DoubleDefault0Adapter implements JsonSerializer<Double>, JsonDeserializer<Double> {
@Override
public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
if (json.getAsString().equals("") || json.getAsString().equals("null")) {// Is defined as double type , If the background comes back "" or null, It returns 0.00
return 0.00;
}
} catch (Exception ignore) {
}
try {
return json.getAsDouble();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
long= >
public class LongDefault0Adapter implements JsonSerializer<Long>, JsonDeserializer<Long> {
@Override
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
if (json.getAsString().equals("") || json.getAsString().equals("null")) {// Is defined as long type , If the background comes back "" or null, It returns 0
return 0l;
}
} catch (Exception ignore) {
}
try {
return json.getAsLong();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
So the usage goes like this:
return new Retrofit.Builder()
.client(okHttpClient)// Set up the network access framework
.addConverterFactory(GsonConverterFactory.create(buildGson()))// add json The transformation framework
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())// let Retrofit support RxJava
.baseUrl(baseUrl)
.build();
/**
* Add background return "" and "null" The processing of
* 1.int=>0
* 2.double=>0.00
* 3.long=>0L
*
* @return
*/
public static Gson buildGson() {
if (gson == null) {
gson = new GsonBuilder()
.registerTypeAdapter(Integer.class, new IntegerDefault0Adapter())
.registerTypeAdapter(int.class, new IntegerDefault0Adapter())
.registerTypeAdapter(Double.class, new DoubleDefault0Adapter())
.registerTypeAdapter(double.class, new DoubleDefault0Adapter())
.registerTypeAdapter(Long.class, new LongDefault0Adapter())
.registerTypeAdapter(long.class, new LongDefault0Adapter())
.create();
}
return gson;
}
Never crash again when the background json field is empty
conclusion
The above is the whole content of this article, I hope the content of this article can help you in your study or work, if you have any questions, you can leave a message to communicate.