又被 fastjson 坑了?它调用了我自定义的 get 方法!

您所在的位置:网站首页 sequencing翻译技巧定义 又被 fastjson 坑了?它调用了我自定义的 get 方法!

又被 fastjson 坑了?它调用了我自定义的 get 方法!

2023-06-03 19:26| 来源: 网络整理| 查看: 265

一、背景

最近看到又有同学被 fastjson 坑了。 该同学在类中自定义了 get 方法,在该 get 方法中引用了一个对象,由于某段代码中 “没有用到”该方法就没注入,最后出现了空指针。 由于自己确定没有主动调用这个方法,排查了半天,借助 arthas 看 trace 才发现这个坑。

二、问题复现 @Data public class Student { private String name; public String getValue() { return "test"; } }

测试:

public class StudentDemo { public static void main(String[] args) { Student student = new Student(); student.setName("Student"); System.out.println(JSON.toJSONString(student)); } }

结果是:{“name”:“Student”,“value”:“test”}

可见 fastjson 的 toJSONString 方法转 JSON 时,底层是通过解析 get 方法来识别属性的,它认为有一个 value 属性,转为 JSON 字符串时会自动调用对应的 get 方法获取 value 属性的值。

如果自定义的 get 方法中使用到了尚没有设置的对象,由于并没有显示调用 getAddress 方法,很多人并不会意识到需要注入 repository 对象,如果调用了 toJSONString 方法就极容易出现空指针异常。

@Data public class Student { private String name; private String addressId; private AddressRepository repository; // 省略其他 public Address getAddress() { return repository.get(addressId); } } public class StudentDemo { public static void main(String[] args) { Student student = new Student(); student.setName("Student"); student.setAddressId("10086"); // 很多人并不会意识到这里会自动调用 getAddress 方法,因此没有设置 repository,空指针了! log.info("过程中某个日志, 参数:{}", JSON.toJSONString(student)); } } 三、如何解决

方法一:自定义的方法避免定义为 get 开头。

import com.alibaba.fastjson.annotation.JSONField; import lombok.Data; @Data public class Student { private String name; public String fetchValue() { return "test"; } }

方法二:使用 @JSONField(serialize = false) 在 getValue 方法上,让 fastjson 忽略该方法。

import com.alibaba.fastjson.annotation.JSONField; import lombok.Data; @Data public class Student { private String name; @JSONField(serialize = false) public String getValue() { return "test"; } } 四、启发

大家在进行项目开发时,当你发现对象转 JSON 字符串时“莫名其妙地”多出了某些属性,其实就是这个原因。 大家在使用 fastjson 将对象转为 JSON 字符串时一定要小心这个坑。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3