2011-12-07 30 views
6

我正在执行杰克逊序列化/反序列化。 举例来说,我有这样的类:杰克逊复杂名单序列化

class Base{ 
    String baseId; 
} 

我想序列名单OBJ文件; 要做到杰克逊,我需要指定一个列表的元素实型,由于Java类型的擦除。 该代码将工作:

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

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

class Result{ 
    List<Base> data; 
} 

我应该如何告诉杰克逊正确序列化这个类?

+1

注意:不建议在原始问题的示例代码中使用TypeFactory。相反,使用mapper.getTypeFactory()。constructCollectionType()。 –

+0

我没有猜到如何将列表指定为constructCollectionType参数。那就是为什么我在那里使用collectionType。 – tmp120210

回答

14

只是

new ObjectMapper().writeValueAsString(myResult); 

类型列表中不会丢失,由于以同样的方式,将在第一个例子类型擦除。


注意,列表或泛型列表的香草系列化,这是没有必要指定列表组件类型,如在原来的问题的例子证明。以下所有三个示例序列化代表具有完全相同JSON的List<Bar>

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;} 
} 

当使用附加类型信息进行序列化时,类型化写入器很有用。请注意下面的json1json3输出是如何不同的。

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} 
    // ] 
    // ] 
    } 
} 
+0

呵呵,我非常接近解决方案)当我第一次尝试时,有东西给了我一个NPE,我认为它不起作用。现在我再试一次,一切正常。谢谢! – tmp120210