您的位置:首页 > 其它

JacksonDemo及使用方法

2014-02-28 11:46 232 查看

JacksonDemo及使用方法

本文依据springside实例,演示Jackson的基本使用方式及大量的特殊Feature.一共13种使用方法。

public class JsonDemo {

 private static JsonMapper mapper =JsonMapper.buildNonDefaultMapper();

 1、序列化对象/集合到Json字符串.
@Test

 public void toJson() throws Exception{
  //Bean
  TestBean bean = newTestBean("A");

  String beanString =mapper.toJson(bean);

  System.out.println("Bean:" +beanString);

  assertEquals("{"name":"A"}",beanString);

  //Map
  Map<String,Object> map = Maps.newLinkedHashMap();

  map.put("name", "A");

  map.put("age", 2);

  String mapString =mapper.toJson(map);

  System.out.println("Map:" +mapString);

  assertEquals("{"name":"A","age":2}",mapString);

  //List<String>
  List<String>stringList = Lists.newArrayList("A", "B", "C");

  String listString =mapper.toJson(stringList);

  System.out.println("StringList:" + listString);

  assertEquals("["A","B","C"]",listString);

  //List<Bean>
  List<TestBean>beanList = Lists.newArrayList(new TestBean("A"), newTestBean("B"));

  String beanListString =mapper.toJson(beanList);
  System.out.println("BeanList:" + beanListString);

  assertEquals("[{"name":"A"},{"name":"B"}]",beanListString);

  //Bean[]
  TestBean[] beanArray =new TestBean[] { new TestBean("A"), new TestBean("B") };

  String beanArrayString =mapper.toJson(beanArray);

  System.out.println("ArrayList:" + beanArrayString);

  assertEquals("[{"name":"A"},{"name":"B"}]",beanArrayString);

}

  2、从Json字符串反序列化对象/集合.
 @Test

 public void fromJson() throws Exception {

  //Bean
  StringbeanString ="{"name":"A"}";
  TestBeanbean = mapper.fromJson(beanString,TestBean.class);
  System.out.println("Bean:"+ bean);

  //Map
  StringmapString ="{"name":"A","age":2}";
  Map<String,Object> map = mapper.fromJson(mapString,HashMap.class);

  System.out.println("Map:");

  for(Entry<String, Object> entry :map.entrySet()) {

   System.out.println(entry.getKey()+ " " + entry.getValue());

  }

  //List<String>
  String listString ="["A","B","C"]";

  List<String>stringList = mapper.fromJson(listString, List.class);

  System.out.println("StringList:");

  for (String element :stringList) {

   System.out.println(element);

  }

  //List<Bean>
  String beanListString= "[{"name":"A"},{"name":"B"}]";

  JavaType beanListType =mapper.constructParametricType(List.class, TestBean.class);

  List<TestBean>beanList = mapper.fromJson(beanListString, beanListType);

  System.out.println("BeanList:");

  for (TestBean element :beanList) {

   System.out.println(element);

  }

 }

 3、 测试三种不同的Binder.
  @Test

 public void threeTypeBinders() {

  TestBean bean = newTestBean("A");

  //打印全部属性
  JsonMappernormalMapper = JsonMapper.buildNormalMapper();

  assertEquals("{"nullValue":null,"name":"A","defaultValue":"hello"}",normalMapper.toJson(bean));

  //不打印nullValue属性
  JsonMappernonNullMapper = JsonMapper.buildNonNullMapper();

  assertEquals("{"name":"A","defaultValue":"hello"}",nonNullMapper.toJson(bean));

  //不打印默认值未改变的nullValue与defaultValue属性
  JsonMappernonDefaultMaper = JsonMapper.buildNonDefaultMapper();

  assertEquals("{"name":"A"}",nonDefaultMaper.toJson(bean));

 }

4、测试传入空对象,空字符串,Empty的集合,"null"字符串的结果.
  @Test

 public void nullAndEmpty() {

  // toJson测试 //

  //NullBean

  TestBean nullBean = null;

  String nullBeanString =mapper.toJson(nullBean);

  assertEquals("null",nullBeanString);

  //EmptyList

  List<String>emptyList = Lists.newArrayList();

  String emptyListString =mapper.toJson(emptyList);

  assertEquals("[]",emptyListString);

  //fromJson测试 //

  //NullString for Bean

  TestBean nullBeanResult =mapper.fromJson(null, TestBean.class);

  assertNull(nullBeanResult);

  nullBeanResult= mapper.fromJson("null", TestBean.class);

  assertNull(nullBeanResult);

  //Null/EmptyString for List

  List nullListResult =mapper.fromJson(null, List.class);

  assertNull(nullListResult);

  nullListResult= mapper.fromJson("null", List.class);

  assertNull(nullListResult);

  nullListResult= mapper.fromJson("[]", List.class);

  assertEquals(0,nullListResult.size());

 }

5、测试对枚举的序列化,可以选择用一个int字段而不是以Name来序列化,以减少少长度.
  @Test

 public void enumData() {

  //默認使用enum.name()

  assertEquals(""One"",mapper.toJson(TestEnum.One));

  assertEquals(TestEnum.One,mapper.fromJson(""One"", TestEnum.class));

  //使用enum.toString()

  //注意,index會通過toString序列成字符串而不是int,否則又和順序號混淆.

  //注意配置必須在所有讀寫動作之前調用.

  JsonMapper newMapper =JsonMapper.buildNormalMapper();

  newMapper.setEnumUseToString(true);

  assertEquals(""1"",newMapper.toJson(TestEnum.One));

  assertEquals(TestEnum.One,newMapper.fromJson(""1"", TestEnum.class));

 }

 枚举的演示Bean.
 publicstatic enum
TestEnum {

  One(1), Two(2),Three(3);

  privateint index;

  TestEnum(intindex) {

   this.index =index;

  }

  @Override

  public String toString(){

   return newInteger(index).toString();

  }

 }

6、测试对日期的序列化.
@Test

 public void dateData() {

  DateTime jodaDate = newDateTime();

  //日期默认以Timestamp方式存储

  Date date = newDate(jodaDate.getMillis());

  String tsString =String.valueOf(jodaDate.getMillis());

  assertEquals(tsString,mapper.toJson(date));

  assertEquals(date,mapper.fromJson(tsString, Date.class));

 }

7、 JSON字符串里只含有Bean中部分的属性,更新一个已存在Bean,只覆蓋部分的属性.
  @Test

 public void updateBean() {

  String jsonString ="{"name":"A"}";

  TestBeanbean = new TestBean();

  bean.setDefaultValue("Foobar");

  bean = mapper.update(bean,jsonString);

  assertEquals("A",bean.getName());

  assertEquals("Foobar",bean.getDefaultValue());

 }

8、测试父子POJO间的循环引用.
@Test

 public void parentChildBean() {

  //初始化对象关系,parent的Childs里含有child1,child2, child1/child2的parent均指向parent.

  ParentChildBean parent = newParentChildBean("parent");

  ParentChildBeanchild1 = new ParentChildBean("child1");

  child1.setParent(parent);

  parent.getChilds().add(child1);

  ParentChildBeanchild2 = new ParentChildBean("child2");

  child2.setParent(parent);

  parent.getChilds().add(child2);

  StringjsonString ="{"childs":[{"name":"child1"},{"name":"child2"}],"name":"parent"}";

  //打印parent的json输出,json字符串裡childs中的child1/child2都不包含到parent的屬性

  assertEquals(jsonString,mapper.toJson(parent));

  //注意此時如果單獨打印child1,也不會打印parent,信息將丟失。

  assertEquals("{"name":"child1"}",mapper.toJson(child1));

  //反向序列化时,Json已很聪明的把parent填入child1/child2中.

  ParentChildBean parentResult =mapper.fromJson(jsonString, ParentChildBean.class);

  assertEquals("parent",parentResult.getChilds().get(0).getParent().getName());

 }

父子POJO父子POJO的演示Bean,@JsonBackReference 与@JsonManagedReference是关键.
 public static class ParentChildBean{

  privateString name;

  private ParentChildBeanparent;

  publicList<ParentChildBean> childs =Lists.newArrayList();

  publicParentChildBean() {

  }

  publicParentChildBean(String name) {

   this.name =name;

  }

  publicString getName() {

   returnname;

  }

  publicvoid setName(String name) {

   this.name =name;

  }

  //注意getter與setter都要添加annotation

  @JsonBackReference
  publicParentChildBean getParent() {

   returnparent;

  }

  @JsonBackReference
  public voidsetParent(ParentChildBean parent) {

   this.parent =parent;

  }

  @JsonManagedReference
  publicList<ParentChildBean> getChilds(){

   returnchilds;

  }

  @JsonManagedReference
  public voidsetChilds(List<ParentChildBean>childs) {

   this.childs =childs;

  }

 }

 9、測試可擴展Bean,會自動的把確定的屬性放入固定的成員變量,其他屬性放到一个类型为Map的成员变量裡,能很好的支持Bean版本升级时固定属性的变动.
  @Test

 public void extensibleBean() {

  //一个没有区分是变量还是Map的普通JSON字符串.

  String jsonString = "{"name": "Foobar","age" : 37,"occupation" : "coder man"}";

  ExtensibleBean extensibleBean =mapper.fromJson(jsonString, ExtensibleBean.class);

  assertEquals("Foobar",extensibleBean.getName());

  assertEquals(null,extensibleBean.getProperties().get("name"));

  assertEquals("coder man",extensibleBean.getProperties().get("occupation"));

 }

演示用的可擴展Bean.@JsonAnySetter与@JsonAnyGetter是关键.
  publicstatic class ExtensibleBean {

  private String name; // wealways have name

  privateHashMap<String, String> properties =Maps.newHashMap();

  publicExtensibleBean() {

  }

  @JsonAnySetter
  public void add(Stringkey, String value) {

   properties.put(key,value);

  }

  @JsonAnyGetter
  publicMap<String, String> getProperties(){

   returnproperties;

  }

  publicString getName() {

   returnname;

  }

  publicvoid setName(String name) {

   this.name =name;

  }

 }

 10、測試序列化Bean时使用不同的View序列化不同的属性组,及@JsonIgnore標註的屬性.
@Test

 public void viewBean() throwsJsonGenerationException, JsonMappingException, IOException {

  ViewBean viewBean = newViewBean();

  viewBean.setName("Foo");

  viewBean.setAge(16);

  viewBean.setOtherValue("others");

  viewBean.setIgnoreValue("ignored");

  ObjectWriterpublicWriter =mapper.getMapper().writerWithView(Views.Public.class);

  assertEquals("{"otherValue":"others","name":"Foo"}",publicWriter.writeValueAsString(viewBean));

  ObjectWriter internalWriter =mapper.getMapper().writerWithView(Views.Internal.class);

  assertEquals("{"age":16,"otherValue":"others"}",internalWriter.writeValueAsString(viewBean));

  //設置默認是否顯示沒有用@Json定義的屬性

  JsonMapper newMapper =JsonMapper.buildNormalMapper();

  newMapper.getMapper().configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION,false);

  publicWriter =newMapper.getMapper().writerWithView(Views.Public.class);

  assertEquals("{"name":"Foo"}",publicWriter.writeValueAsString(viewBean));

 }

 public static classViews {

  static class Public {

  }

  staticclass Internal {

  }

 }

  演示序列化不同View不同属性的Bean.
 public staticclass ViewBean {

  private String name;

  private int age;

  private StringotherValue;

  private StringignoreValue;

  @JsonView(Views.Public.class)

  public String getName() {

   returnname;

  }

  publicvoid setName(String name) {

   this.name =name;

  }

  @JsonView(Views.Internal.class)

  public int getAge() {

   returnage;

  }

  publicvoid setAge(int age) {

   this.age =age;

  }

  publicString getOtherValue() {

   returnotherValue;

  }

  publicvoid setOtherValue(String otherValue) {

   this.otherValue= otherValue;

  }

  @JsonIgnore

  public String getIgnoreValue(){

   returnignoreValue;

  }

  publicvoid setIgnoreValue(String ignoreValue) {

   this.ignoreValue= ignoreValue;

  }

 }

 11、测试自定义转换器
  @Test

 public void customConverter(){

  JsonMappernewMapper = JsonMapper.buildNonNullMapper();

  SimpleModule testModule = newSimpleModule("MyModule", new Version(1, 0, 0, null));

  testModule.addSerializer(newMoneySerializer()); // assuming serializer declares correct classto bind to

  testModule.addDeserializer(Money.class,new MoneyDeserializer());

  newMapper.getMapper().registerModule(testModule);

  Moneymoney = new Money(1.2);

  StringjsonString = newMapper.toJson(money);

  assertEquals(""1.2"",jsonString);

  MoneyresultMoney = newMapper.fromJson(jsonString,Money.class);

  assertEquals(newDouble(1.2), resultMoney.value);

 }

 public class MoneySerializer extendsSerializerBase<Money> {

  public MoneySerializer(){

   super(Money.class);

  }

  publicvoid serialize(Money value, JsonGenerator jgen, SerializerProviderprovider) throws IOException,

    JsonProcessingException{

   jgen.writeString(value.toString());

  }

 }

 public class MoneyDeserializer extendsStdDeserializer<Money> {

  public MoneyDeserializer(){

   super(Money.class);

  }

  @Override

  public Moneydeserialize(JsonParser jp, DeserializationContext ctxt) throwsIOException,

    JsonProcessingException{

   returnMoney.valueOf(jp.getText());

  }

 }

 publicstatic class Money {

  private Doublevalue;

  publicMoney(Double value) {

   this.value =value;

  }

  publicstatic Money valueOf(String value) {

   DoublesrcValue = Double.valueOf(value);

   return newMoney(srcValue);

  }

  publicString toString() {

   returnvalue.toString();

  }

 }

 12、测试修改属性名策略
  @Test

 public void customPropertyNameing() throwsJsonMappingException {

  TestBeanbean = new TestBean("foo");

  bean.setDefaultValue("bar");

  JsonMapper newMapper =JsonMapper.buildNonNullMapper();

  newMapper.getMapper().setPropertyNamingStrategy(newLowerCaseNaming());

  String jsonpString =newMapper.toJson(bean);

  assertEquals("{"name":"foo","defaultvalue":"bar"}",jsonpString);

 }

 publicstatic class LowerCaseNaming extends PropertyNamingStrategy {

  @Override

  public StringnameForGetterMethod(MapperConfig<?>config, AnnotatedMethod method, String defaultName) {

   returndefaultName.toLowerCase();

  }

 }

 13、測試輸出jsonp格式內容.
@Test

 public void jsonp() {

  TestBean bean = newTestBean("foo");

  String jsonpString =mapper.toJsonP("callback", bean);

  assertEquals("callback({"name":"foo"})",jsonpString);

 }

 演示Bean,主要演示不同風格的Mapper對Null值,初始化後沒改變過的屬性值的處理.
  public staticclass TestBean {

  privateString name;

  private String defaultValue ="hello"; //默认值没被修改过的属性,可能会不序列化

  private String nullValue =null; //空值的据行,可能会不序列化

  publicTestBean() {

  }

  publicTestBean(String name) {

   this.name =name;

  }

  publicString getName() {

   returnname;

  }

  publicvoid setName(String name) {

   this.name =name;

  }

  publicString getDefaultValue() {

   returndefaultValue;

  }

  publicvoid setDefaultValue(String defaultValue) {

   this.defaultValue= defaultValue;

  }

  publicString getNullValue() {

   returnnullValue;

  }

  publicvoid setNullValue(String nullValue) {

   this.nullValue= nullValue;

  }

  @Override

  public String toString(){

   return"TestBean [defaultValue=" + defaultValue + ", name=" + name + ",nullValue=" + nullValue + "]";

  }

 }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: