Gson中使用TypeAdapter设置默认值,如数字类型Long默认是null,但是我们需要0
Gson非常好用,但在对接后台接口时,经常碰到这样的问题,就是我们前端使用了long(基本)类型,但是后台使用了Long(封装)类型,而Long默认值为null,所以接口返回的数据中有些是非必要的可能为null,这样就会导致我们解析失败,整体数据都解析出错,这是我们不期望的,有人会说我们前端也用Long类型不就好了吗?的确用Long类型解析不会出错,但是却有另一个问题,在对两个数操作时却出现空指针异常,导致应用闪退,我们总不能在所有使用到的地方都加空判断吧,所以就有了本文的解决方法。
假如我们有如下的一个Bean:
public class Entity {
private long code;
private String message;
public void setCodelong code) {
this.code = code;
}
public long getCode() {
return code;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
我们需要当后台返回的code为null时,默认转为0,避免程序出现异常,这时候就需要用到TypeAdapter,如下定义一个处理long的默认为0的TypeAdapter:
import android.util.Log;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.toprank.byd_b.utils.NumberUtils;
/**
* Created by Chenguandu on 2017-9-4.
*/
public class LongTypeAdapter extends TypeAdapter {
@Override
public void write(JsonWriter out, Long value) {
try {
if (value == null){
value = 0L;
}
out.value(value);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Long read(JsonReader in){
try {
Long value;
if (in.peek() == JsonToken.NULL) {
in.nextNull();
Log.e("TypeAdapter", "null is not a number");
return 0L;
}
if (in.peek() == JsonToken.BOOLEAN) {
boolean b = in.nextBoolean();
Log.e("TypeAdapter", b + " is not a number");
return 0L;
}
if (in.peek() == JsonToken.STRING) {
String str = in.nextString();
if (NumberUtils.isInt(str)){
return Long.parseLong(str);
} else {
Log.e("TypeAdapter", str + " is not a int number");
return 0L;
}
} else {
value = in.nextLong();
return value;
}
} catch (Exception e) {
Log.e("TypeAdapter", "Not a number", e);
}
return 0L;
}
}
同理int如下:
import android.util.Log;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.toprank.byd_b.utils.NumberUtils;
/**
* Created by Chenguandu on 2017-9-4.
*/
public class IntegerTypeAdapter extends TypeAdapter {
@Override
public void write(JsonWriter out, Integer value) {
try {
if (value == null){
value = 0;
}
out.value(value);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Integer read(JsonReader in) {
try {
Integer value;
if (in.peek() == JsonToken.NULL) {
in.nextNull();
Log.e("TypeAdapter", "null is not a number");
return 0;
}
if (in.peek() == JsonToken.BOOLEAN) {
boolean b = in.nextBoolean();
Log.e("TypeAdapter", b + " is not a number");
return 0;
}
if (in.peek() == JsonToken.STRING) {
String str = in.nextString();
if (NumberUtils.isInt(str)){
return Integer.parseInt(str);
} else {
Log.e("TypeAdapter", str + " is not a int number");
return 0;
}
} else {
value = in.nextInt();
return value;
}
} catch (Exception e) {
Log.e("TypeAdapter", "Not a number", e);
}
return 0;
}
}
double如下:
import android.util.Log;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.toprank.byd_b.utils.NumberUtils;
/**
* Created by Chenguandu on 2017-9-4.
*/
public class DoubleTypeAdapter extends TypeAdapter {
@Override
public void write(JsonWriter out, Double value) {
try {
if (value == null){
value = 0D;
}
out.value(value);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Double read(JsonReader in) {
try {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
Log.e("TypeAdapter", "null is not a number");
return 0D;
}
if (in.peek() == JsonToken.BOOLEAN) {
boolean b = in.nextBoolean();
Log.e("TypeAdapter", b + " is not a number");
return 0D;
}
if (in.peek() == JsonToken.STRING) {
String str = in.nextString();
if (NumberUtils.isFloat(str)){
return Double.parseDouble(str);
} else {
Log.e("TypeAdapter", str + " is not a number");
return 0D;
}
} else {
Double value = in.nextDouble();
return value == null ? 0D : value;
}
}catch(NumberFormatException e){
Log.e("TypeAdapter", e.getMessage(), e);
} catch (Exception e) {
Log.e("TypeAdapter", e.getMessage(), e);
}
return 0D;
}
}
Float如下:
import android.util.Log;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.toprank.byd_b.utils.NumberUtils;
/**
* Created by Chenguandu on 2017-9-4.
*/
public class FloatTypeAdapter extends TypeAdapter {
@Override
public void write(JsonWriter out, Float value) {
try {
if (value == null){
value = 0F;
}
out.value(value.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Float read(JsonReader in) {
try {
Float value;
if (in.peek() == JsonToken.NULL) {
in.nextNull();
Log.e("TypeAdapter", "null is not a number");
return 0F;
}
if (in.peek() == JsonToken.BOOLEAN) {
boolean b = in.nextBoolean();
Log.e("TypeAdapter", b + " is not a number");
return 0F;
}
if (in.peek() == JsonToken.STRING) {
String str = in.nextString();
if (NumberUtils.isFloat(str)){
return Float.parseFloat(str);
} else {
Log.e("TypeAdapter", str + " is not a number");
return 0F;
}
} else {
String str = in.nextString();
value = Float.valueOf(str);
}
return value;
} catch (Exception e) {
Log.e("TypeAdapter", "Not a number", e);
}
return 0F;
}
}
使用方法如下:
public Gson buildGson() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Integer.class, new IntegerTypeAdapter())
.registerTypeAdapter(int.class, new IntegerTypeAdapter())
.registerTypeAdapter(Double.class, new DoubleTypeAdapter())
.registerTypeAdapter(double.class, new DoubleTypeAdapter())
.registerTypeAdapter(Long.class, new LongTypeAdapter())
.registerTypeAdapter(long.class, new LongTypeAdapter())
.registerTypeAdapter(Float.class, new FloatTypeAdapter())
.registerTypeAdapter(float.class, new FloatTypeAdapter())
.create();
return gson;
}
这样处理以后,不管理我们前端使用的是基本类型还是封装类型,也不管理接口返回的是不是null或者不是数字,都不会出现异常,如果接口返回的不是数字或是null则自动赋值为0