🌞

FastJson 反序列化部分字段为 Null

⚠ 使用 FastJson 将 json 文件反序列化为 JavaBean 出现字段缺失 ⚠

问题复现

FastJson 版本:1.2.70

1
2
3
4
5
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.70</version>
</dependency>

json 内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
  "properties": {
    "jobName": "this_is_a_test",
    "description": "for test json"
  },
  "task": [
    {
      "name": "task_1",
      "type": "test",
      "className": "com.jjmeg.Task",
      "args": {
        "topic": "mockTopic",
        "username": "mockPin",
        "password": "mockPasswd"
      }
    }
  ]
}

设计的 JavaBean:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class Flow {
    public Map<String, String> properties;
    public List<Task> task;

    @Override
    public String toString() {
        return "Flow{" +
                "properties='" + properties + '\'' +
                ", task='" + task +'\'' +
                '}';
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public class Task implements Serializable {
    public String name;

    public String type;

    public String className;

    public Map<String, String> args;

    // 含参构造函数、无默认构造函数
    public Task(String name) {
        this.name = name;
    }

    public static void main(String[] args) throws ConfigurationException, IOException {
        String text = IOUtils.toString(new FileInputStream(filePath), StandardCharsets.UTF_8);
        Flow flow = JSON.parseObject(text, Flow.class);
    }
}

运行结果中,Task的内容有缺失:

1
Task{name='task_1', type='null', className='null', args=null}

问题原因:

FastJson 反序列过程中,使用默认的构造函数创建实例,在没有默认构造函数情况下,FastJson 使用含参的构造函数。

Task 类中,构造函数被重写为 Task(String name),则只有 name 字段被赋值,同理,该示例中,只定义含三个参数的构造函数 public Task(String name, String className, String type) ,反序列化的 Task 对象的 args 属性为 null

解决办法:

添加无参构造函数或含所有参数的构造函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 无参函数
public Task() {
}

// 含所有参数的构造函数
public Task(String name, String className, String type, Map<String, String> args) {
    this.name = name;
    this.args = args;
    this.type = type;
    this.className = className;
}
updatedupdated2020-07-222020-07-22