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

  • 相关阅读:
    absolute 导致点击事件无效
    windows 下的命令操作
    localStorage 设置本地缓存
    css渐变
    vue-cli webpack全局引入jquery
    #024分段函数。
    #023单词接龙1(字符串)(女友)
    #022 Python 实验课
    #021 Java复习第一天
    #020PAT 没整明白的题L1-009 N个数求和 (20 分)
  • 原文地址:https://www.cnblogs.com/winkey4986/p/5865853.html
Copyright © 2011-2022 走看看