2011-12-07 32 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