Ding

FastJSON(1.1.52.android)解析Json字符串的一个坑

背景

最近在捣鼓一个应用,用到了 JSON 串格式如下:

其中,有一个字段: _id ,按照以往的经验,解析这个串,对应的 JavaBean 格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Bean{
private String _id;
private String createdAt;
private String desc;
private String source;
private String type;
private String url;
private boolean used;
private String who;
private String publishedAt;
public void setXXX(){...}
public T getXXX{...}
}

好的,看似没什么问题,解析也不报错,但是 debug 的时候发现,_id 字段没有数据,其他的都好好的,why?

问题在哪?

花了点时间追进去看发现,原来并不是我们的 JavaBean 格式有问题,是 FastJson 解析的时候,帮我们做了一些“不必要”的操作。
在 FastJson 源码中的 JavaBeanInfo.class,这个类的 434 行,他帮我们把 “_” 给去掉了裁剪掉了(心好累…
导致的问题就是在匹配网络数据中获取的 JSON 串时,无法命中 “_id” 字段,因为此时我们本地的 Bean 文件反射出来的 field 从 “_id” –> “id”, 从而无法正确的获取到 “_id” 字段的值了…

为什么要这么做?

从变量名你大概就能看出他获取字段属性的方式了,是从 class 的 method 中,裁剪 set 方法来获取这个 propertyName 接着会跟整个 Bean 文件中声明的字段进行比较,来确保每个字段跟 setXXX 能匹配上。假如匹配不上你不可能乱 set 值吧,对吧,不然打不死你…

解决办法

既然他要裁一个,那咱们就加一个好喽,让本地的属性能匹配到网络数据中的 “_id” ,like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Bean{
private String __id;
private String createdAt;
private String desc;
private String source;
private String type;
private String url;
private boolean used;
private String who;
private String publishedAt;
public void setXXX(){...}
public T getXXX{...}
}

结语

最后就能得到数据了:

一些疑问

Q:为什么不直接用 Bean 文件的 field 字段来进行 JSON 串的匹配?
A:因为 Bean 文件里没有 set 方法时,然后你的 field 又是 private 的时候你怎么处理呢?

你的认可是我最大的动力!