【问题标题】:List to .json and to list with object class name列出到 .json 并列出对象类名称
【发布时间】:2021-08-20 16:31:23
【问题描述】:

我有不同对象的列表

  List<Object> people = new ArrayList<>();
    people.add(new Worker("John", "Bep", "Farmer", 2500));
    people.add(new Teacher("Jacob", "Hiu", 2, "Biology"));
    people.add(new PoliceMan("Zoe", "Clain", 35, 2800));

我需要从该列表中创建 .json 文件。然后我需要打印这个文件,其中包含对象类的所有属性和名称,如下所示:

Worker: name:John, surname:Bep, work:Farmer,salary:2500

我已经这样做了:

public String listToJson() throws JsonProcessingException {
    List<Object> people = new ArrayList<>();
    people.add(new Worker("John", "Bep", "Farmer", 2500));
    people.add(new Teacher("Jacob", "Hiu", 2, "Biology"));
    people.add(new PoliceMan("Zoe", "Clain", 35, 2800));

    String s = objectMapper.writeValueAsString(people);
    return s;
}

public void jsonToList() throws IOException {
    String s = listToJson();
    TypeReference<List<Object>> mapType = new TypeReference<List<Object>>() {};
    List<Object>jsonToOList= objectMapper.readValue(s,mapType);
    jsonToOList.forEach(System.out::println);
  
}

我也继承了List&lt;Person&gt; people,但它返回了相同的结果。

现在的输出是:{name:John, surname:Bep, work:Farmer,salary:2500} 没有worker

【问题讨论】:

标签: java json jackson


【解决方案1】:

如果还需要反序列化,则提供完整的类名是不可避免的,如下解决方案;

@Test
void t1() throws Exception {
    // init
    List<Person> people = new ArrayList<>();
    people.add(new Worker("John", "Bep", "Farmer", 2500));
    people.add(new Teacher("Jacob", "Hiu", 2, "Biology"));
    people.add(new PoliceMan("Zoe", "Clain", 35, 2800));
    people.add(new PoliceMan("Joe", "Plain", 35, 2800));

    // serialize
    ObjectMapper om = new ObjectMapper();
    JavaType plType = om.getTypeFactory().constructCollectionLikeType(List.class, Person.class);

    //serialize
    String s = om.writerFor(plType).writeValueAsString(people);
    System.out.println(s);

    //deserialize
    List<Person> p = om.readValue(s, om.getTypeFactory().constructCollectionLikeType(List.class, Person.class));
    System.out.println(p.get(0).getClass().getSimpleName());

}

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.WRAPPER_OBJECT)
public static abstract class Person {
    String name;
    String surname;

    public Person() {
    }

    public Person(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }

    public String getName() {
        return name;
    }

    public String getSurname() {
        return surname;
    }
}

public static class Worker extends Person {
    String work;
    int salary;

    public Worker() {
        super();
    }

    public Worker(String name, String surname, String work, int salary) {
        super(name, surname);
        this.work = work;
        this.salary = salary;
    }

    public String getWork() {
        return work;
    }

    public int getSalary() {
        return salary;
    }
}

public static class Teacher extends Person {
    String branch;
    int classes;

    public Teacher() {
        super();
    }

    public Teacher(String name, String surname, int classes, String branch) {
        super(name, surname);
        this.branch = branch;
        this.classes = classes;
    }

    public String getBranch() {
        return branch;
    }

    public int getClasses() {
        return classes;
    }
}

public static class PoliceMan extends Person {
    int precinct;
    int salary;

    public PoliceMan() {
        super();
    }

    public PoliceMan(String name, String surname, int precinct, int salary) {
        super(name, surname);
        this.precinct = precinct;
        this.salary = salary;
    }

    public int getPrecinct() {
        return precinct;
    }

    public int getSalary() {
        return salary;
    }
}

输出如下;

[
  {
    "some.package.name$Worker": {
      "name": "John",
      "surname": "Bep",
      "work": "Farmer",
      "salary": 2500
    }
  },
  {
    "some.package.name$Teacher": {
      "name": "Jacob",
      "surname": "Hiu",
      "branch": "Biology",
      "classes": 2
    }
  },
  {
    "some.package.name$PoliceMan": {
      "name": "Zoe",
      "surname": "Clain",
      "precinct": 35,
      "salary": 2800
    }
  },
  {
    "some.package.name$PoliceMan": {
      "name": "Joe",
      "surname": "Plain",
      "precinct": 35,
      "salary": 2800
    }
  }
]

【讨论】:

  • 现在打印没有属性的 Worker, Teacher,PoliceMan
  • 这可能与版本有关。我正在使用带有 fasterxml 2.12.3 的 Java 11,并且测试序列化和反序列化数组没有任何问题。还有一件事,如果你看到空对象,这可能意味着映射器找不到合适的序列化器并回退到 UnknownSerializer。因此,请确保 JavaType 的构造正确......
【解决方案2】:

如果这是您正在寻找的答案;

[
  {
    "Worker": {
      "name": "John",
      "surname": "Bep",
      "work": "Farmer",
      "salary": 2500
    }
  },
  {
    "Teacher": {
      "name": "Jacob",
      "surname": "Hiu",
      "branch": "Biology",
      "classes": 2
    }
  },
  {
    "PoliceMan": {
      "name": "Zoe",
      "surname": "Clain",
      "precint": 35,
      "salary": 2800
    }
  },
  {
    "PoliceMan": {
      "name": "Joe",
      "surname": "Plain",
      "precint": 35,
      "salary": 2800
    }
  }
]

那么你可以在没有任何注释的情况下进行如下操作;


    @Test
    void t1() throws Exception {
        // init
        List<Person> people = new ArrayList<>();
        people.add(new Worker("John", "Bep", "Farmer", 2500));
        people.add(new Teacher("Jacob", "Hiu", 2, "Biology"));
        people.add(new PoliceMan("Zoe", "Clain", 35, 2800));

        //test
        ObjectMapper om = new ObjectMapper();

        String s = om.writeValueAsString(
                people.stream().map(
                        p-> Collections.singletonMap(p.getClass().getSimpleName(), p)
                ).collect(Collectors.toList())
        );

        System.out.println(s);
    }


    // Assuming you have such pojo classes...

    private class Person {
        String name;
        String surname;
        public Person(String name, String surname) {
            this.name = name;
            this.surname = surname;
        }
        public String getName() {
            return name;
        }
        public String getSurname() {
            return surname;
        }
    }

    private class Worker extends Person {
        String work;
        int salary;
        public Worker(String name, String surname, String work, int salary) {
            super(name, surname);
            this.work = work;
            this.salary = salary;
        }
        public String getWork() {
            return work;
        }
        public int getSalary() {
            return salary;
        }
    }

    private class Teacher extends Person {
        String branch;
        int classes;
        public Teacher(String name, String surname, int classes, String branch) {
            super(name, surname);
            this.branch = branch;
            this.classes = classes;
        }
        public String getBranch() {
            return branch;
        }
        public int getClasses() {
            return classes;
        }
    }

    private class PoliceMan extends Person {
        int precint;
        int salary;
        public PoliceMan(String name, String surname, int precint, int salary) {
            super(name, surname);
            this.precint = precint;
            this.salary = salary;
        }
        public int getPrecint() {
            return precint;
        }
        public int getSalary() {
            return salary;
        }
    }

【讨论】:

  • 我有 pojo 课程。 t1 方法返回是可以的,但我需要将人员列表写入 json,然后读取这个 json 文件并打印它。我需要序列化和反序列化这个列表。
  • 那么你必须使用 JsonTypeInfo 和完整的 className...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-07
  • 2021-10-27
相关资源
最近更新 更多