简体   繁体   English

杰克逊:自定义集合序列化到JSON

[英]Jackson : custom collection serialization to JSON

I am trying to json-serialize a class MyRootClass with a property that is a collection of elements of a second class MyClass: 我正在尝试json序列化一个MyRootClass类,其属性是第二个类MyClass的元素集合:

public class MyRootClass {
   private List<MyInterface> list = new ArrayList<MyInterface>();
   // getter / setter
}

public class MyClass implements MyInterface {
   private String value = "test";    
   // getter / setter
}

The following code: 以下代码:

MyRootClass root = new MyRootClass();
root.getList().add(new MyClass());
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(System.out, root);

Generates this JSON output: 生成此JSON输出:

{"list": [ {"value":"test"} ] }

instead of what I need, every object in the collection serialized with a name: 而不是我需要的,集合中的每个对象都用一个名称序列化:

{"list": [ {"myclass": {"value":"test"}} ] }

Is there any way to achieve it using Jackson? 有没有办法用Jackson实现它? I thought about writing a custom serializer, but I've not found anything related to a collection of objects. 我考虑过编写自定义序列化程序,但是我没有找到任何与对象集合相关的内容。

It depends on what exactly you want to achieve with name; 这取决于你想用名字实现什么; but yes, this can be done if you want to include 'myclass' here is type information (or can act as if it was used; if you do not use Jackson to deserialize it does not really matter). 但是,如果你想在这里包含'myclass'是类型信息(或者可以表现得好像它被使用;如果你不使用Jackson反序列化它并不重要),这可以做到。

If so, you would annotate MyInterface: 如果是这样,您将注释MyInterface:

@JsonTypeInfo(use=Id.NAME, include=As.WRAPPER_OBJECT)

and MyClass with: 和MyClass:

@JsonTypeName("myclass")

(if you don't define that, default name would be unqualified name of the class) (如果没有定义,默认名称将是该类的非限定名称)

@JsonTypeInfo above defines that type name is to be used (instead of Java class name, or custom method), and inclusion is done by using a wrapper object (alternatives are wrapper array and as-property) 上面的@JsonTypeInfo定义了要使用的类型名称(而不是Java类名或自定义方法),并且使用包装器对象完成包含(替代方法是包装器数组和as-property)

So you should then see expected output. 那么你应该看到预期的输出。

What you want is to include the name of the class in the output. 你想要的是在输出中包含类的名称。 This is not how json serializers behave - they include only field names. 这不是json序列化程序的行为方式 - 它们只包含字段名称。

What you can do is to introduce another class. 你能做的是介绍另一堂课。

class MyClass implements MyInterface {
    private MyOtherClass myclass;
}

class MyOtherClass {
    private String value = "test";
}

You can use a helper object like this: 您可以使用这样的辅助对象:

public static class MyObject {
    public int i;
    public MyObject(int i) { this.i = i; }
    public MyObject() {}
}

@JsonDeserialize(contentAs=MyObject.class)
public static class MyHelperClass extends ArrayList<MyObject> {

}

@Test
public void testCollection() throws JsonGenerationException, JsonMappingException, IOException {
    final Collection<MyObject> l = new ArrayList<MyObject>();
    l.add(new MyObject(1));
    l.add(new MyObject(2));
    l.add(new MyObject(3));

    final ObjectMapper mapper = new ObjectMapper();

    final String s = mapper.writeValueAsString(l);
    final Collection<MyObject> back = mapper.readValue(s, MyHelperClass.class);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM