当前位置: 首页 > 知识库问答 >
问题:

使用Jackson序列化类型化集合时出错

叶景龙
2023-03-14

我试图使用混合序列化集合,但Jackson不会保存类型信息。这是一个基本测试,说明会发生什么:

public class CollectionSerializationTest {

    interface Common extends Serializable {

    }

    class A implements Common {
        private static final long serialVersionUID = 1L;
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
    @JsonSubTypes({ @JsonSubTypes.Type(value = A.class, name = "CODE") })
    class AMixIn {

    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
    @JsonSubTypes({ @JsonSubTypes.Type(value = B.class, name = "CODE") })
    class BMixIn {

    }

    class B implements Common {
        private static final long serialVersionUID = 1L;
    }

    @Test
    public void test() throws JsonGenerationException, JsonMappingException,
            IOException {
        ObjectMapper om = new ObjectMapper();
        List<Common> list = new ArrayList<Common>();
        A a = new A();
        B b = new B();
        list.add(a);
        list.add(b);
        om.getSerializationConfig().addMixInAnnotations(A.class, AMixIn.class);
        om.getSerializationConfig().addMixInAnnotations(B.class, BMixIn.class);
        System.out.println(om.writeValueAsString(list)); // Outputs [{},{}]
        System.out.println(om.writeValueAsString(a));// Outputs {"type":"CODE"}
    }

}

如何在第一个输出上实现输出[{“type”:“code”},{“type”:“code”}]

共有1个答案

南门正业
2023-03-14

我不确定这是否是最简单的解决方案,但我认为你可以这样做:

  1. 创建新列表实施
  2. 为新类型编写序列化程序
  3. 在POJO类中使用此类型

扩展了ArrayList的新Java类:

@JsonSerialize(using = JacksonListSerializer.class)
class JacksonList<E> extends ArrayList<E> {

    private static final long serialVersionUID = 1L;
}

上述类的序列化程序:

class JacksonListSerializer extends JsonSerializer<JacksonList<?>> {

    @Override
    public void serialize(JacksonList<?> list, JsonGenerator generator, SerializerProvider provider)
            throws IOException, JsonProcessingException {
        generator.writeStartArray();
        if (list != null) {
            for (Object item : list) {
                generator.writeObject(item);
            }
        }
        generator.writeEndArray();
    }
}

现在,您可以在示例中使用此列表:

public static void main(String[] args) throws IOException {
    ObjectMapper om = new ObjectMapper();
    List<Common> list = new JacksonList<Common>();
    list.add(new A());
    list.add(new B());
    om.addMixInAnnotations(A.class, AMixIn.class);
    om.addMixInAnnotations(B.class, BMixIn.class);
    System.out.println(om.writeValueAsString(list));
    System.out.println(om.writeValueAsString(new A()));
}

上面的示例打印:

[{"type":"CODE"},{"type":"CODE"}]
{"type":"CODE"}
 类似资料:
  • 我用Jackson编写了自己的序列化程序。它接受一个变量或类,并返回任何简单类型的值。 示例:serialize(new MyClass(2.0))将返回一个值为 2.0 的双精度值,其中 MyClass 如下所示: 因此,为了获得正确的值,我需要设置@JsonValue,但是,当我序列化一个没有@JsonValue注释的对象(例如UUID)时,它会返回预期的UUID字符串。 创建我自己的类没有@

  • 问题内容: 我有一个json字符串,应该将其反序列化为以下类 我该怎么做?这是通常的方式 但是我怎么提到T代表什么呢? 问题答案: 你需要为使用的每种通用类型创建一个对象,并将其用于反序列化。例如

  • 我有一个json字符串,我应该将其反序列化为以下类 我怎么做?这是通常的方式 但我怎么说T代表什么呢?

  • 问题内容: 我正在尝试制作一个使用Jackson来反序列化POJO的类。 看起来像这样… 我对此实施有2个问题。 首先是我将类类型传递给方法,以便对象映射器知道应反序列化的类型。有使用泛型的更好方法吗? 同样在get方法中,我将一个从objectMapper返回的对象强制转换为T。这看起来特别讨厌,因为我必须在此处强制转换T,然后还必须从调用它的方法中强制转换对象类型。 我在该项目中使用了Robo

  • 如果我有课 其中,MySet扩展了Set。杰克逊抱怨说 我理解,但我已经实例化了集合。我希望杰克逊在创建实例后为每个值调用,类似于: 我不希望它试图自己创建一个新的集合。