和后台进行数据交互时,后台可能给出类似与这样的JSON数据格式:
{
"StringIsNull":null,
"DoubleIsNUll":null,
"LongIsNull":null,
"ObjectIsNull":null,
"ArrayIsNull":null,
"ObjectConvertString":{
"item1":"v1",
"item2":{
"i3":"d1",
"i4":"d2"
}
}
}
复制代码
而我们一般用new Gson().fromJson()
,去转换成Bean。Bean里面的字段就会被赋值为Null,引用的时候就会报空指针异常并且闪退(强烈建议去跟后台刚,实在刚不过,就接着看....)。
Gson如何将jsonString转成Bean?
先跟踪下代码看看:(注释在代码里面,一张张图仔细看哦)
-
0
-
1
-
2
-
3
-
4、实际处理的地方
-
5
-
6、这里声明了对应的实现工厂类
- 7、看下String工厂这么被添加实现的(这个图应该截TypeAdapter的,不过不影响分析)
详细分析都在图片里面了
怎么更改相应的工厂实现类?
根据上面的分析,如果要改成其为null时的字段赋值为'',就必须要重写对应的Adapter。如TypeAdapter ,而Gson中自带的TypeAdapter,是static final 并且初始化好了。反射更改肯定走不通了。
Gson其实是用GsonBuilder生成的。而GsonBuilder里面有一个方法registerTypeAdapter()
示例实现更改返回的String为null时,赋值为""
相关的Adapter 拷贝出来,然后在return 返回相应的初始化值即可。
特殊情况 如:Long Double Float这种,有基本类型(long,double,float)时,直接在实体类中字段类型改成基本类型,就会自动转成默认值。
public class GsonUtils {
private static Gson gson;
//String 拷贝出来就可以了。
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
@Override
public String read(JsonReader in) throws IOException {
JsonToken peek = in.peek();
if (peek == JsonToken.NULL) {
in.nextNull();
return "";
}
/* coerce booleans to strings for backwards compatibility */
if (peek == JsonToken.BOOLEAN) {
return Boolean.toString(in.nextBoolean());
}
return in.nextString();
}
@Override
public void write(JsonWriter out, String value) throws IOException {
out.value(value);
}
};
//根据GsonBuilder 创建Gson
static {
GsonBuilder gsonBuilder=new GsonBuilder();
//注册registerTypeAdapter 就可以了
gsonBuilder.registerTypeAdapter(String.class, STRING);
gson=gsonBuilder.create();
}
/**
* Json字符串 转为指定对象
*
* @param json json字符串
* @param type 对象类型
* @param <T> 对象类型
* @return
* @throws JsonSyntaxException
*/
public static <T> T toBean(String json, Type type) throws JsonSyntaxException {
T obj = gson.fromJson(json, type);
return obj;
}
}
复制代码
测试后结果如下:
//原始数据
{"StringIsNull":null,"DoubleIsNUll":null,"LongIsNull":null}
//正常使用new Gson().fromJson()后的数据
{StringIsNull='null', DoubleIsNUll=null, LongIsNull=null}
//注册TypeAdapter<String>和更改Double为double,Long为long后的数据
{StringIsNull='', DoubleIsNUll=0.0, LongIsNull=0}
复制代码
还有以下几个问题,将会在下篇中解决
- 1、Object返回为null时,或者非Object时,处理成自动new Obejct();
- 2、Array列表为null时,处理成自动new ArrayList<>();