前提
fastjson调用JSON.toJSONString(Object object)时,出现了生成的JSONString中的key与object中实际key不同的情况
图中data的analyse成员变量在序列化之后的key竟然变成了复数analyses
爬坑
于是果断在Data类的analyse成员变量上增加注解@JSONField
public static class Data{ @JSONField(name = "time") private long time; @JSONField(name = "score") private int score; @JSONField(name = "analyse") private List<Analyse> analyse; @JSONField(name = "tip") private List<String> tip; public long getTime() { return time; } public int getScore() { return score; } public List<Analyse> getAnalyses() { return analyse; } public List<String> getTip() { return tip; } public void setTime(long time) { this.time = time; } public void setScore(int score) { this.score = score; } public void setAnalyse(List<Analyse> analyse) { this.analyse = analyse; } public void setTip(List<String> tip) { this.tip = tip; } }
发现结果还是一样的,序列化时analyse成员变量的key依然是analyses
于是开始排查get方法,发现analyse成员变量的get方法多了一个s,几乎可以认为这个坑可以爬出来了。但是想试一下如果不改get方法的方法名,而是将注解@JSONField放到get和set方法上,会不会也能解决。
public static class Data{ private long time; private int score; private List<Analyse> analyse; private List<String> tip; @JSONField(name = "time") public long getTime() { return time; } @JSONField(name = "score") public int getScore() { return score; } @JSONField(name = "analyse") public List<Analyse> getAnalyses() { return analyse; } @JSONField(name = "tip") public List<String> getTip() { return tip; } @JSONField(name = "time") public void setTime(long time) { this.time = time; } @JSONField(name = "score") public void setScore(int score) { this.score = score; } @JSONField(name = "analyse") public void setAnalyse(List<Analyse> analyse) { this.analyse = analyse; } @JSONField(name = "tip") public void setTip(List<String> tip) { this.tip = tip; } }
此时序列化得到的analyse字段的key是正确的
结论
- fastjson在序列化对象时,key不是根据成员变量的变量名来决定的,而是对应的get方法的函数名
- 如果在变量名上添加@JSONField注解,并不会使该成员变量在序列化时使用注解中的key,需要将注解加到该成员变量的get和set方法上
- 我们甚至可以额外的添加get方法,来在序列化的时候添加新的字段,而不局限于成员变量