在研发工程中,当我们与服务器进行数据交互的时候,会定义数据格式,而Json是十分常用的格式。而对Json的格式化也是我们常要用到的,一般我会引入第三方框架来帮助我们进行解析工作。如Gson、fastJson、jackson等。
有时候,由于前后台一些数据格式的不一致或者默认值的不一致,会导致解析失败或者解析出来的数据我们在使用的时候有问题的情况。通常我使用Gson比较多,所以这里解析以Gson来举例如下:
我们的Json:{"result":0,"id":1,"data":"ABC"}
我们的实体类:
public class UserBean {
public int result;
public long id;
public String data;
@Override
public String toString() {
return "result:"+result+" id:"+id+" data:"+data;
}
}
我们用Gson解析:
Gson gson = new Gson();
Log.e("CALM",jsonStr);
UserBean bean = gson.fromJson(jsonStr,UserBean.class);
Log.e("CALM",bean.data);
这里的jsonStr就是我们上面的json字符串
输出结果如下:
{result:0,id:1,data:"ABC"}
ABC
可以看到这样是没有任何问题的。But,如果我们的json是这样的{"result":0,"id":1,"data":null}就是如果说我们后台的同事对字符串的默认值为null,我们在尝试运行刚才的代码会发现程序崩溃,抛出异常java.lang.NullPointerException: println needs a message,实际在我们打印Log.e("CALM",bean.data); 这句的时候出现的,因为我们输出的null不符合Log的输出规则,它要求的是字符串。实际不光是字符串,如果后台给我们的result默认为null,而我们希望默认为-1怎么办呢?
其实这时候我们可以自定义TypeAdapter来解决。我们先将json字符串改成这样:{"result":null,"id":1,"data":null},而我们希望解析出来result = -1,data = "Empty",默认值可以自己根据实际定义。
首先编写int的adapter 在里面,我们将null的情况赋值为-1
public class IntegerAdapter extends TypeAdapter {
@Override
public void write(JsonWriter out, Integer value) throws IOException {
try {
if(value == null){
value = -1;
}
out.value(value);
}catch (Exception e){
}
}
@Override
public Integer read(JsonReader in) throws IOException {
try {
Integer value;
if(in.peek() == JsonToken.NULL) {
in.nextNull();
return -1;
}
if(in.peek() == JsonToken.BOOLEAN){
boolean b = in.nextBoolean();
return b?1:-1;
}
if(in.peek() == JsonToken.STRING){
//这里按自己意愿进行处理
return 0;
}else {
value = in.nextInt();
return value;
}
}catch (Exception e){
}
return -1;
}
}
在编写一个String的adapter 我们将null的情况赋值为了Empty
public class StringAdapter extends TypeAdapter {
@Override
public void write(JsonWriter out, String value) throws IOException {
try {
if(TextUtils.isEmpty(value)){
value = "Empty";
}
out.value(value);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public String read(JsonReader in) throws IOException {
try {
String value;
if(JsonToken.NULL == in.peek()){
in.nextNull();
return "Empty";
}else {
return in.nextString();
}
}catch (Exception e){
}
return "Empty";
}
}
修改我们创建Gson的代码
Gson gson = new GsonBuilder()
.registerTypeAdapter(String.class,new StringAdapter())
.registerTypeAdapter(Integer.class,new IntegerAdapter())
.registerTypeAdapter(int.class,new IntegerAdapter())
.create();
//Gson gson = new Gson();
Log.e("CALM",jsonStr);
UserBean bean = gson.fromJson(jsonStr,UserBean.class);
Log.e("CALM",bean.toString());
然后我们调用看下日志
{result:null,id:1,data:null}
result:-1 id:1 data:Empty
可以看到我们解析之后result = -1,data = "Empty"这是符合我们的预期的。
当然对于其余的数据类型,也是可以按自己的实际情况定义之后去处理的,这样我们就定义了统一的结果处理机制了。