反序列化为未定义的泛型类型的列表

Deserialization to a list of undefined generic type

提问人:primož perušek 提问时间:11/10/2023 最后编辑:primož perušek 更新时间:11/13/2023 访问量:51

问:

我定义了一个类 Person:

public static class Person{
    private String name;
    private String surname;
    // Getters, setters, contructor...
}

我运行以下代码:

@Test
public void minimalGenericJackson() throws JsonProcessingException {
    List list = new ArrayList();
    list.add(23);
    list.add(new Person("John", "Doe"));

    ObjectMapper objectMapper = new ObjectMapper();

    final String json = objectMapper.writeValueAsString(list);


    final List outList = objectMapper.readValue(json, List.class);
    final Person person = (Person) outList.get(1);
}

必须序列化 Json 字符串,然后反序列化为 java 对象。在反序列化过程结束时,我需要将 Person 项反序列化为 Person 类型的 Object,但在我的情况下,它不是它,它被反序列化为 LinkedHashMap。如果可能的话,我需要一个不更改测试代码的 sloution,只更改 Person.java 代码。

我运行的代码产生以下异常:

java.lang.ClassCastException:类 java.util.LinkedHashMap 不能 投射到类 de.mpg.ipp.codac.archivedb.restapi.JsonTestsPlayground$Person (java.util.LinkedHashMap 位于加载器“bootstrap”的 java.base 模块中; de.mpg.ipp.codac.archivedb.restapi.JsonTestsPlayground$Person 在 加载器“app”的未命名模块)

是否可以通过向 Person 类添加 Jackson 注释来解决此问题。也许通过定义 Person 类来获取附加类型属性。就像它是使用 和 完成的,但在我的情况下我没有设法使用它们,因为 person 不是我另一类的子类型。另外,我想避免启用默认输入。@JsonTypeInfo@JsonSubTypes

List 应具有未定义的泛型类型,因为它可能包含任何基元值和/或 Person 对象。我的问题的目标是成功反序列化包含 Person 对象和其他基元值的 List。

TypeReference在这种情况下不能使用,因为 List 包含变量基元类型和 Person 对象的值。JavaType

java json 杰克逊

评论

0赞 Mark Rotteveel 11/10/2023
您需要将适当的类型传递给 。 是不够的。请参阅 Jackson 和泛型类型参考 和 如何使用 Jackson 反序列化泛型 List<T>?readValueList.class
0赞 primož perušek 11/10/2023
该列表应具有未定义的泛型类型,因为它可能包含任何基元值和/或 Person 对象。这是要求之一。将添加到描述
0赞 Mark Rotteveel 11/10/2023
你不能有一个未定义的类型,因为这样 Jackson 就无法选择类型,而是使用 .据我所知,唯一的选择是拥有一个通用接口并使用类型信息来描述适当的类型(但也许还有更高级的技巧)。LinkedHashMap

答:

0赞 Ahmed Mera 11/13/2023 #1

你得到这个错误是因为你不能将 HashMap 转换为你的自定义对象,所以如果你想有一个 Geeric 列表,你必须在每次 HashMap 转换为你的自定义对象时。

DSO的

public static class Person{
    private String name;
    private String surname;
    // Getters, setters, contructor...
}

您可以运行以下代码,它将起作用:

@Test
public void minimalGenericJackson() throws JsonProcessingException {
        List<Object> list = new ArrayList<>();
        list.add(23);
        list.add(new Person("John", "Doe"));

        ObjectMapper objectMapper = new ObjectMapper();

        final List<Object> outList = objectMapper.convertValue(list, new TypeReference<>() {
        });
        System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(outList));

        final Person person = objectMapper.convertValue(outList.get(1), Person.class);
        System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(person));
}

评论

0赞 primož perušek 11/13/2023
主要挑战是为 Person 类或映射器功能提供注释,这将使反序列化能够生成 Person 类型而不是 LinkedHashMap 类型的 Person 对象
0赞 Ahmed Mera 11/13/2023
我想你不能那样做......