我正在开发Jackson序列化/反序列化.
例如,我有这样的课程:
例如,我有这样的课程:
class Base{ String baseId; }
我想序列化列表objs;
要使用jackson,我需要指定列表的元素实际类型,因为java类型擦除.
此代码将起作用:
List<Base> data = getData(); return new ObjectMapper().writerWithType(TypeFactory.collectionType(List.class,Base.class)).writeValueAsString(data);
现在,我想序列化更复杂的类:
class Result{ List<Base> data; }
我应该如何告诉杰克逊正确序列化这门课程?
解决方法
只是
new ObjectMapper().writeValueAsString(myResult);
由于类型擦除,列表的类型不会像第一个示例中那样丢失.
请注意,对于列表或通用列表的vanilla序列化,没有必要指定列表组件类型,如原始问题中的示例所示.以下所有三个示例序列化代表List< Bar>使用完全相同的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","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","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输出有何不同.
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",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",// {"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",// {"type":"com.stackoverflow.q8416904.Zab","hungry":true} // ] // ] // } mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD,"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",// {"type":"com.stackoverflow.q8416904.Zab","hungry":true} // ] // ] } }