杰克逊复杂列表序列化 [英] Jackson complex list serialization

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

问题描述

我正在开发杰克逊序列化/反序列化。
例如,我有这样的类:

I'm experementing with Jackson serialization/deserialization. For instance, I have such class:

class Base{
    String baseId;
}

我想序列化列表objs;
要使用jackson,我需要指定列表的元素实数类型,因为java类型擦除。
此代码可以使用:

And I want to serialize List objs; To do it with jackson, I need to specify a list's elements real type, due to the java type erasure. This code will work:

List<Base> data = getData();
return new ObjectMapper().writerWithType(TypeFactory.collectionType(List.class, Base.class)).writeValueAsString(data);

现在,我想序列化更复杂的类:

Now, I want to serialize more complex class:

class Result{
     List<Base> data;
}

我应该如何告诉Jackson正确序列化这个课程?

How should I tell Jackson to properly serialize this class?

推荐答案

只需

new ObjectMapper().writeValueAsString(myResult);

列表类型不会因类型擦除而丢失,其方式与在第一个例子中。

The type of the list won't be lost due to type erasure in the same way it would be in the first example.

注意,对于列表或通用列表的vanilla序列化,没有必要指定列表组件类型,如原始问题中的示例所示。以下所有三个示例序列化都代表 List< Bar> ,具有完全相同的JSON。

Note that for vanilla serialization of a list or generic list, it's not necessary to specify the list component types, as demonstrated in the example in the original question. All three of the following example serializations represent the List<Bar> with the exact same JSON.

import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    Baz baz = new Baz("BAZ", 42);
    Zab zab = new Zab("ZAB", true);
    List<Bar> bars = new ArrayList<Bar>();
    bars.add(baz);
    bars.add(zab);

    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);

    String json1 = mapper.writeValueAsString(bars);
    System.out.println(json1);
    // output:
    // [{"name":"BAZ","size":42},{"name":"ZAB","hungry":true}]

    Foo foo = new Foo(bars);

    String json2 = mapper.writeValueAsString(foo);
    System.out.println(json2);
    // output:
    // {"bars":[{"name":"BAZ","size":42},{"name":"ZAB","hungry":true}]}

    mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
    ObjectWriter typedWriter = mapper.writerWithType(mapper.getTypeFactory().constructCollectionType(List.class, Bar.class));

    String json3 = typedWriter.writeValueAsString(bars);
    System.out.println(json3);
    // output:
    // [{"name":"BAZ","size":42},{"name":"ZAB","hungry":true}]
  }
}

class Foo
{
  List<Bar> bars;
  Foo(List<Bar> b) {bars = b;}
}

abstract class Bar
{
  String name;
  Bar(String n) {name = n;}
}

class Baz extends Bar
{
  int size;
  Baz(String n, int s) {super(n); size = s;}
}

class Zab extends Bar
{
  boolean hungry;
  Zab(String n, boolean h) {super(n); hungry = h;}
}

使用其他类型信息进行序列化时,类型编写器非常有用。注意下面的 json1 json3 输出如何不同。

A typed writer is useful when serializing with additional type information. Note how the json1 and json3 outputs below differ.

import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectMapper.DefaultTyping;
import org.codehaus.jackson.map.ObjectWriter;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    Baz baz = new Baz("BAZ", 42);
    Zab zab = new Zab("ZAB", true);
    List<Bar> bars = new ArrayList<Bar>();
    bars.add(baz);
    bars.add(zab);

    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
    mapper.enableDefaultTypingAsProperty(DefaultTyping.OBJECT_AND_NON_CONCRETE, "type");

    String json1 = mapper.writeValueAsString(bars);
    System.out.println(json1);
    // output:
    // [
    //   {"type":"com.stackoverflow.q8416904.Baz","name":"BAZ","size":42},
    //   {"type":"com.stackoverflow.q8416904.Zab","name":"ZAB","hungry":true}
    // ]

    Foo foo = new Foo(bars);

    String json2 = mapper.writeValueAsString(foo);
    System.out.println(json2);
    // output:
    // {
    //   "bars":
    //   [
    //     "java.util.ArrayList",
    //     [
    //       {"type":"com.stackoverflow.q8416904.Baz","name":"BAZ","size":42},
    //       {"type":"com.stackoverflow.q8416904.Zab","name":"ZAB","hungry":true}
    //     ]
    //   ]
    // }

    mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
    mapper.enableDefaultTypingAsProperty(DefaultTyping.OBJECT_AND_NON_CONCRETE, "type");
    ObjectWriter typedWriter = mapper.writerWithType(mapper.getTypeFactory().constructCollectionType(List.class, Bar.class));

    String json3 = typedWriter.writeValueAsString(bars);
    System.out.println(json3);
    // output:
    // [
    //   "java.util.ArrayList",
    //   [
    //     {"type":"com.stackoverflow.q8416904.Baz","name":"BAZ","size":42},
    //     {"type":"com.stackoverflow.q8416904.Zab","name":"ZAB","hungry":true}
    //   ]
    // ]
  }
}

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

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