前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >又被 fastjson 坑了?它调用了我自定义的 get 方法!

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

作者头像
明明如月学长
发布2023-05-19 15:38:42
9250
发布2023-05-19 15:38:42
举报
文章被收录于专栏:明明如月的技术专栏

一、背景

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

二、问题复现

代码语言:javascript
复制
@Data
public class Student {

    private String name;

    public String getValue() {
        return "test";
    }
}

测试:

代码语言:javascript
复制
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 方法就极容易出现空指针异常。

代码语言:javascript
复制
@Data
public class Student {

    private String name;

    private String addressId;

    private AddressRepository repository;


    // 省略其他
    public Address getAddress() {
        return repository.get(addressId);
    }
}
代码语言:javascript
复制
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 开头。

代码语言:javascript
复制
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 忽略该方法。

代码语言:javascript
复制
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 字符串时一定要小心这个坑。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023/05/18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、背景
  • 二、问题复现
  • 三、如何解决
  • 四、启发
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档