(de)序列化杰克逊的嵌套泛型 [英] (de)serialising Nested Generics in Jackson

查看:123
本文介绍了(de)序列化杰克逊的嵌套泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在寻求使用Jackson对一个对象进行反序列化和序列化。该对象具有层次结构,并且在层次结构的深处有一个

So I am seeking to deserialise and serialise an object using Jackson. The object has a hierarchy, and deep down in the hierachy there is a

List<T>

其中T是String或其中一个Java数字类。

where T is either a String, or one of the Java number classes.

反序列化通用列表一直是这些论坛的常见主题,我知道如何构建一个映射器,使用mapper.readValue对列表进行反序列化或序列化。

Deserialising generic lists has been a common topic on these forums, and I know how to build a mapper that will deserialise or serialise a list using mapper.readValue.

我不知道该怎么做是因为当我在顶级调用mapper时,它不明确地知道它包含的类的参数化,这样它就会知道当它到达包含参数化列表的底层类时如何调用自定义反序列化器。

What I don't know how to do is make is so that when I call the mapper on the top level, which doesn't know explicitly about the parametrisation of the classes that it contains, such that it will know how to call the custom deserialiser when it gets to the bottom level class that contains the parameterised list.

省略了getters / setters / constructors的简单示例:

A simple example with getters/setters/constructors ommitted:

class A {
    String name;
    B thing;
}

class B {
    String command;
    List<C<?>> conditions;
}

class C<T> {
    String type;
    List<T> parameters
}

我想写一个连续序列化A的Jackson命令。我一直在使用附加到A的方法:

And I want to write a Jackson command that serialises A in one go. I have been using a method attached to A:

public String toJSON() throws JsonProcessingException{
    ObjectMapper mapper = new ObjectMapper();
    mapper.enableDefaultTyping();
    return mapper.writeValueAsString(this);
}

但这已知通用集合丢失其类型信息而不是deserialisable。

but this has the known issue of generic collections losing their type information and not being deserialisable.

我可以使用这里的建议使用泛型参数反序列化给定的类,但我不知道如何组合这些解决方案。我希望杰克逊有一些我为C编写的自定义反序列化器,当它到达那个类类型时它可以使用它,否则它可以使用普通的序列化器,它适用于其他类。

I can use the advice here to deserialise a given class with a generic parameter, but I don't see how to combine these solutions. I was hoping that Jackson has some what that I an write a custom deserialiser for C, and it can use that when it reaches that class type, and otherwise it can use the normal serialiser, which works fine for the other classes.

推荐答案

当Jackson将您的JSON反序列化为 A 类型的对象时,它会看到反序列化其 B 字段时的以下内容

When Jackson is deserializing your JSON into an object of type A, it sees the following when deserializing for its B field

List<C<?>> conditions;

你(程序员)和杰克逊都不知道什么类型的 C 参数字段应该有。因此,它没有足够的信息来反序列化,就像你想要的那样。相反,它将使用其默认类型,我认为是 LinkedHashMap (或类似的东西)。

Neither you (the programmer), nor Jackson know what type C's parameters field should have. As such, it doesn't have enough information to deserialize like you would want it. Instead, it will use its default type which I believe is a LinkedHashMap (or something similar).

基本上,你唯一的选择是给它提示。 (自定义)使用 String 值序列化对象层次结构以反序列化为。然后,您可以为自定义反序列化器中的每种类型设置不同的策略。

Basically, your only option is to give it hints. (Custom) Serialize the object hierarchy with a String value of the Class to deserialize to. You can then have a different strategy for each of those types in your custom deserializer.

由于您只有几种类型, String 或其中一个 Number 类,您可能更适合编写泛型类 C 和X非每种类型的通用类

Since you only have a few types, String or one of the Number classes, you might be better served writing a generic class C and X non generic classes for each of the types

class C<T> {}
class StringC extends C<String> {}
class IntegerC extends C<Integer> {}

并使用一些多态类型处理以序列化/反序列化。

and use some polymorphic type handling to serialize/deserialize.

这篇关于(de)序列化杰克逊的嵌套泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆