和后台进行数据交互时,后台可能给出类似与这样的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 TypeAdapterSTRING = new TypeAdapter () { @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 对象类型 * @return * @throws JsonSyntaxException */ public static 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和更改Double为double,Long为long后的数据 {StringIsNull='', DoubleIsNUll=0.0, LongIsNull=0}复制代码
还有以下几个问题,将会在下篇中解决
- 1、Object返回为null时,或者非Object时,处理成自动new Obejct();
- 2、Array列表为null时,处理成自动new ArrayList<>();