zoukankan      html  css  js  c++  java
  • Jackson学习笔记(三)<转>

    概述

    使用jackson annotations简化和增强的json解析与生成。

    Jackson-2.x通用annotations列表:https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations

    Jackson-1.x通用annotations列表:http://wiki.fasterxml.com/JacksonAnnotations

    准备工作

    基于JDK1.7,依赖Jackson框架核心类库:

    jackson-core-2.5.3.jar
    jackson-annotations-2.5.3.jar
    jackson-databind-2.5.3.jar

    Jackson - Annotations

    想要了解更多内容,请查看annotations列表。下面只列出一些常用的Json注解。

    @JsonProperty

    它关联json字段到Java属性。可以标记属性,也可以用来标记属性的getter/setter方法。当标记属性时,可以对属性字段重命名。当标记方法时,可以把json字段关联到java属性的getter或setter方法。

    @JsonCreator

    json反序列化为java对象时,该注解用于定义构造函数。当从json创建java时,@JsonCreator注解的构造函数被会调用,如果没有@JsonCreator注解,则默认调用java类的无参构造函数,此时,如果java类中只有有参构造函数,而无默认的无参构造函数,在反序列化时会抛出这样的异常:com.fasterxml.jackson.databind.JsonMappingException,所以,当我们不使用@JsonCreator指定反序列化的构造函数,而又在java类中重载了构造函数时,一定要记得编写类的无参构造函数。

    @JsonAnyGetter@JsonAnySetter

    用于标记类方法,设置和读取json字段作为键值对存储到map中,这两个注解标记的方法不会处理任何java类中已经定义过的属性变量,只对java中未定义的json字段作处理。

    @JsonIgnoreProperties@JsonIgnore

    用于标记属性,在json与java之间相互转化时,将忽略被此注解标记的属性。@JsonIgnoreProperties是类级别注解,可以忽略多个属性,@JsonIgnore用来标注单个属性。

    @JsonTypeInfo@JsonSubTypes

    用于维持java类的子类信息,将子类对象类型信息嵌入到json中,以便反序列化创建具体的对象。

    Example

    下面通过例子来演示注解的使用

    example.1

    读取company.json,反序列化json,创建java对象,并遍历信息

    company.json

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. {  
    2.   "name" : "Oracle",  
    3.   "HQ" : "California",  
    4.   "birthDate" : "1977-01-01",  
    5.   "departments" : [ {  
    6.     "name" : "development",  
    7.     "employee_number" : 5000,  
    8.     "projectManager" : "jack",  
    9.     "product" : "oracle_db"  
    10.   }, {  
    11.     "name" : "test",  
    12.     "employee_number" : 500,  
    13.     "projectManager" : "rose",  
    14.     "product" : "oracle_test"  
    15.   } ]  
    16. }  

    Company.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.annotation;  
    2.   
    3. import java.util.Date;  
    4.   
    5. import com.fasterxml.jackson.annotation.JsonCreator;  
    6. import com.fasterxml.jackson.annotation.JsonIgnore;  
    7. import com.fasterxml.jackson.annotation.JsonProperty;  
    8.   
    9. public class Company {  
    10.     private String name;  
    11.     @JsonProperty("HQ")   //java属性headquarters序列化到json字段的名称为HQ  
    12.     private String headquarters;  
    13.     private Department[] departments;  
    14.     @JsonIgnore         //在序列化与反序列化时,忽略birthDate属性  
    15.     private Date birthDate;  
    16.   
    17.     public Date getBirthDate() {  
    18.         return birthDate;  
    19.     }  
    20.   
    21.     @JsonCreator  
    22.     public Company(@JsonProperty("name") String name) {  
    23.         this.name = name;  
    24.     }  
    25.   
    26.     public String getName() {  
    27.         return name;  
    28.     }  
    29.   
    30.     public String getHeadquarters() {  
    31.         return headquarters;  
    32.     }  
    33.   
    34.     public Department[] getDepartments() {  
    35.         return departments;  
    36.     }  
    37.   
    38.     public void setDepartments(Department[] departments) {  
    39.         this.departments = departments;  
    40.     }  
    41.   
    42. }  

    Department.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.annotation;  
    2.   
    3. import java.util.HashMap;  
    4. import java.util.Map;  
    5.   
    6. import com.fasterxml.jackson.annotation.JsonAnyGetter;  
    7. import com.fasterxml.jackson.annotation.JsonAnySetter;  
    8. import com.fasterxml.jackson.annotation.JsonCreator;  
    9. import com.fasterxml.jackson.annotation.JsonProperty;  
    10.   
    11. public class Department {  
    12.     private String name;  
    13.     private String pm;  
    14.     private Map<String, Object> otherProperties = new HashMap<String, Object>(); //otherProperties用来存放Department中未定义的json字段  
    15.       
    16.     @JsonCreator   //指定json反序列化创建Department对象时调用此构造函数  
    17.     public Department(@JsonProperty("name") String name){  
    18.         this.name = name;  
    19.     }  
    20.       
    21.     @JsonProperty("projectManager")  //将company.json中projectManager字段关联到getPm方法  
    22.     public String getPm() {  
    23.         return pm;  
    24.     }  
    25.   
    26.     public String getName() {  
    27.         return name;  
    28.     }  
    29.   
    30.     public Object get(String key) {  
    31.         return otherProperties.get(key);  
    32.     }  
    33.   
    34.     @JsonAnyGetter    //得到所有Department中未定义的json字段的  
    35.     public Map<String, Object> any() {  
    36.         return otherProperties;  
    37.     }  
    38.   
    39.     @JsonAnySetter  
    40.     public void set(String key, Object value) {  
    41.         otherProperties.put(key, value);  
    42.     }  
    43.   
    44. }  


    DeserializationExample.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.annotation;  
    2.   
    3. import java.io.File;  
    4.   
    5. import com.fasterxml.jackson.databind.DeserializationFeature;  
    6. import com.fasterxml.jackson.databind.ObjectMapper;  
    7.   
    8. public class DeserializationExample {  
    9.     public static void main(String[] args) throws Exception {  
    10.         ObjectMapper mapper = new ObjectMapper();  
    11.         mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); //禁止未知属性打断反序列化  
    12.           
    13.         Company company = mapper.readValue(new File("company_back.json"), Company.class);  
    14.         System.out.print("company_name:"+company.getName()+" ");  
    15.         System.out.print("headquarters:"+company.getHeadquarters()+" ");  
    16.         System.out.println("birthDate:"+company.getBirthDate()); //birthDate被标记为@JsonIgnore,所以此处得到的值应该为null  
    17.           
    18.         Department[] departments = company.getDepartments();  
    19.           
    20.         for (Department department : departments) {  
    21.             System.out.print("department_name:" + department.getName()+" ");  
    22.             System.out.print("employee_number:" + department.getPm()+" ");  
    23.             //Department中未定义的字段product,employee_number  
    24.             System.out.print("product:"+department.get("product")+" ");   
    25.             System.out.println("projectManager:"+department.get("employee_number"));  
    26.         }  
    27.     }  
    28.   
    29. }  


    程序运行控制台打印结果如下:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. company_name:Oracle headquarters:California birthDate:null  
    2. department_name:development employee_number:jack    product:oracle_db   projectManager:5000  
    3. department_name:test    employee_number:rose    product:oracle_test projectManager:500  


    example.2

    下面例子演示,当java对象中包含List<Object>属性时,如何序列化与反序列化。

    当java对象中含List<Object>时,如果Object一个抽象类或接口,这里就会出现java多态的现象,比如,List<Animal>,Animal是个抽象类,并且有多个子类时,由于List中保存的Animal没有明确指向具体的子类或实现类,json反序列化java对象时就会抛出提示:Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException:Can not construct instance of Animal, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information

    @JsonTypeInfo与@JsonSubTypes就是解决此类问题,通过注解,可以在序列化时,保存具体的类型信息到json中,当json反序列到java对象时,就可以根据具体类型信息创建正确的java对象。

    Zoo.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.databinding.list;  
    2.   
    3. import java.util.List;  
    4.   
    5. import com.fasterxml.jackson.annotation.JsonCreator;  
    6. import com.fasterxml.jackson.annotation.JsonProperty;  
    7.   
    8. public class Zoo {  
    9.     public String name;  
    10.     public String city;  
    11.     public List<Animal> animals;  
    12.       
    13.     @JsonCreator  
    14.     public Zoo(@JsonProperty("name") String name, @JsonProperty("city") String city) {  
    15.         this.name = name;  
    16.         this.city = city;  
    17.     }  
    18.       
    19.     public void setAnimals(List<Animal> animals) {  
    20.         this.animals = animals;  
    21.     }  
    22.   
    23.     @Override  
    24.     public String toString() {  
    25.         return "Zoo [name=" + name + ", city=" + city + ", animals=" + animals  
    26.                 + "]";  
    27.     }  
    28.       
    29. }  

    Animal.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.databinding.list;  
    2.   
    3. import com.fasterxml.jackson.annotation.JsonSubTypes;  
    4. import com.fasterxml.jackson.annotation.JsonSubTypes.Type;  
    5. import com.fasterxml.jackson.annotation.JsonTypeInfo;  
    6. import com.fasterxml.jackson.annotation.JsonTypeInfo.As;  
    7. import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;  
    8.   
    9. @JsonTypeInfo(use=Id.CLASS,include=As.PROPERTY,property="@class")  
    10. @JsonSubTypes({@Type(value=Lion.class,name="lion"),@Type(value=Elephant.class,name="elephant")})  
    11. public abstract class Animal {  
    12.     String name;  
    13.     String type;  
    14. }  

    Lion.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.databinding.list;  
    2.   
    3. import com.fasterxml.jackson.annotation.JsonCreator;  
    4. import com.fasterxml.jackson.annotation.JsonProperty;  
    5.   
    6. public class Lion extends Animal {  
    7.       
    8.     private String name;  
    9.       
    10.     @JsonCreator  
    11.     public Lion(@JsonProperty("name") String name) {  
    12.         this.name = name;  
    13.     }  
    14.   
    15.     public String getName() {  
    16.         return name;  
    17.     }  
    18.       
    19.     public String getType() {  
    20.         return "carnivorous";  
    21.     }  
    22.   
    23.     @Override  
    24.     public String toString() {  
    25.         return "Lion [name=" + name + ", getName()=" + getName()  
    26.                 + ", getType()=" + getType() + "]";  
    27.     }  
    28.       
    29. }  

    Elephant.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.databinding.list;  
    2.   
    3. import com.fasterxml.jackson.annotation.JsonCreator;  
    4. import com.fasterxml.jackson.annotation.JsonProperty;  
    5.   
    6. public class Elephant extends Animal {  
    7.     private String name;  
    8.   
    9.     @JsonCreator  
    10.     public Elephant(@JsonProperty("name") String name) {  
    11.         this.name = name;  
    12.     }  
    13.       
    14.     public String getName() {  
    15.         return name;  
    16.     }  
    17.       
    18.     public String getType() {  
    19.         return "herbivorous";  
    20.     }  
    21.   
    22.     @Override  
    23.     public String toString() {  
    24.         return "Elephant [getName()=" + getName() + ", getType()=" + getType()  
    25.                 + "]";  
    26.     }  
    27.       
    28. }  


    SerializeExmaple.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.databinding.list;  
    2.   
    3. import java.io.File;  
    4. import java.io.IOException;  
    5. import java.util.ArrayList;  
    6. import java.util.List;  
    7.   
    8. import com.fasterxml.jackson.databind.ObjectMapper;  
    9. import com.fasterxml.jackson.databind.SerializationFeature;  
    10.   
    11. public class SerializeExample {  
    12.     public static void main(String[] args) throws Exception {  
    13.         Zoo zoo = new Zoo("SH Wild Park", "ShangHai");  
    14.         Lion lion = new Lion("Samba");  
    15.         Elephant elephant = new Elephant("Manny");  
    16.         List<Animal> animals = new ArrayList<Animal>();  
    17.         animals.add(lion);  
    18.         animals.add(elephant);  
    19.         zoo.setAnimals(animals);  
    20.           
    21.         ObjectMapper mapper = new ObjectMapper();  
    22.         mapper.configure(SerializationFeature.INDENT_OUTPUT, true);  
    23.         mapper.writeValue(new File("zoo.json"), zoo);  
    24.     }  
    25.   
    26. }  

    生成zoo.json内容如下:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. {  
    2.   "name" : "SH Wild Park",  
    3.   "city" : "ShangHai",  
    4.   "animals" : [ {  
    5.     "@class" : "com.jackson.json.databinding.list.Lion",  
    6.     "name" : "Samba",  
    7.     "type" : "carnivorous"  
    8.   }, {  
    9.     "@class" : "com.jackson.json.databinding.list.Elephant",  
    10.     "name" : "Manny",  
    11.     "type" : "herbivorous"  
    12.   } ]  
    13. }  


    反序列化,DeserializeExmaple.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.databinding.list;  
    2.   
    3. import java.io.File;  
    4.   
    5. import com.fasterxml.jackson.databind.ObjectMapper;  
    6.   
    7. public class DeserializeExample {  
    8.   
    9.     public static void main(String[] args) throws Exception {  
    10.         ObjectMapper mapper = new ObjectMapper();  
    11.         Zoo zoo = mapper.readValue(new File("zoo.json"), Zoo.class);  
    12.         System.out.println(zoo);  
    13.     }  
    14. }  


    这里对反序列化后的Zoo对象不作详细遍历了,只打印toString看一下,结果如下,正确创建了Lion和Elephant对象

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. Zoo [name=SH Wild Park, city=ShangHai, animals=[Lion [name=Samba, getName()=Samba, getType()=carnivorous], Elephant [getName()=Manny, getType()=herbivorous]]]  



    我们还可以用另一个种方法来替代JsonSubTypes注释,现在,我们对Animal.java类稍作修改,隐去@JsonSubTypes注解,保留@JsonInfoType注解.这一次,我们直接序列化List<Animal>

    SerializeExample2.java

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.jackson.json.databinding.list;  
    2.   
    3. import java.io.File;  
    4. import java.io.IOException;  
    5. import java.util.ArrayList;  
    6. import java.util.List;  
    7.   
    8. import com.fasterxml.jackson.core.type.TypeReference;  
    9. import com.fasterxml.jackson.databind.ObjectMapper;  
    10. import com.fasterxml.jackson.databind.SerializationFeature;  
    11.   
    12. public class SerializeExample {  
    13.     public static void main(String[] args) throws Exception {  
    14.         Zoo zoo = new Zoo("SH Wild Park", "ShangHai");  
    15.         Lion lion = new Lion("Samba");  
    16.         Elephant elephant = new Elephant("Manny");  
    17.         List<Animal> animals = new ArrayList<Animal>();  
    18.         animals.add(lion);  
    19.         animals.add(elephant);  
    20.         zoo.setAnimals(animals);  
    21.           
    22.         ObjectMapper mapper = new ObjectMapper();  
    23.         mapper.configure(SerializationFeature.INDENT_OUTPUT, true);  
    24.         mapper.writerFor(new TypeReference<List<Animal>>() {  
    25.         }).writeValue(new File("animal.json"), animals);  
    26.           
    27.     }  
    28.   
    29. }  

    生成 animal.json,内容如下:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. [ {  
    2.   "@class" : "com.jackson.json.databinding.list.Lion",  
    3.   "name" : "Samba",  
    4.   "type" : "carnivorous"  
    5. }, {  
    6.   "@class" : "com.jackson.json.databinding.list.Elephant",  
    7.   "name" : "Manny",  
    8.   "type" : "herbivorous"  
    9. } ]  

    总结

    当采用数据绑定(DataBinding)方式处理json时,适当的使用Jackson Annotations可以帮助我们更好的解决问题,特别体现在序列化List时,解决多态的问题,以保证反序化到java对象时的正确性。@JsonAnyGetter,@JsonAnySetter,@JsonProperty都是很常用的注解,可以帮助我们更简洁的处理java对象与json之间的相互转化。

    转自 http://blog.csdn.net/java_huashan/article/details/46428971

  • 相关阅读:
    hdu 5119 Happy Matt Friends
    hdu 5128 The E-pang Palace
    hdu 5131 Song Jiang's rank list
    hdu 5135 Little Zu Chongzhi's Triangles
    hdu 5137 How Many Maos Does the Guanxi Worth
    hdu 5122 K.Bro Sorting
    Human Gene Functions
    Palindrome(最长公共子序列)
    A Simple problem
    Alignment ( 最长上升(下降)子序列 )
  • 原文地址:https://www.cnblogs.com/winkey4986/p/5865853.html
Copyright © 2011-2022 走看看