jackson

本文详细介绍Java中使用fastjson、jackson进行JSON解析的方法,包括依赖引入、JSON字符串与Java对象互转、节点操作及生成JSON字符串等,并提供代码示例。

java中使用fastjson、jackson、json-lib解析JSON-------------------妈妈再也不用担心JSON解析

1、fastjson
引入包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.16</version>
</dependency>

JSON字符串转JSONObject/JSONArray
JSONObject jsonObject = JSONObject.parseObject(jsonString);
得到子节点
jsonObject .getString();
jsonObject .getArray();
jsonObject .getDate();
.....
转为javaBean
JSONObject.toJavaObject(jsonObject,JavaBean.class);
JSON字符串直接转JavaBean
JSONObject.parseObject(jsonString,javaBean.class);
JavaBean转JSON字符串
String jsonString = JSONObject.toJSONString(javaBean)

2、jackson

引入的包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.0</version>
</dependency>

JSON字符串装javaBean
objectMapper = new ObjectMapper();
JavaBean javaBean= objectMapper.readValue(jsonString, JavaBean.class);

javaBean转JSON字符串
objectMapper = new ObjectMapper();
//writeObject可以转换java对象,eg:JavaBean/Map/List/Array等

String jsonString = objectMapper.writeValueAsString(bean);

控制台打印:

jsonGenerator.writeObject(bean); 
//writeValue具有和writeObject相同的功能
objectMapper.writeValue(System.out, bean);

 

获取子节点
ObjectMapper mapper = new ObjectMapper(); 
// 读取json,将整个json作为根节点 
JsonNode node = mapper.readTree(jsonString);

node.path();
node.get();

 

1. //如果属性没有值,那么Json是会处理的,int类型为0,String类型为null,数组为[],设置这个特性可以忽略空值属性 
2. mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); 
3. //让Json可以缩进,可读性更好,一般用在测试和开发阶段。 
4. mapper.configure(SerializationFeature.INDENT_OUTPUT, true); 
5. //让map的key按自然顺序排列 
6. mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true); 
7. //日期输出格式 
8. SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd"); 
9. mapper.setDateFormat(outputFormat);

创建节点,生成JSON字符串
1. //创建一个提供所有节点的JsonNodeFactory,false表示不创建DecimalNode 
2. JsonNodeFactory factory = new JsonNodeFactory(false); 
3. 
4. // 创建JsonFactory,使用Streaming API的方式输出到控制台 
5. JsonFactory jsonFactory = new JsonFactory(); 
6. JsonGenerator generator = jsonFactory.createGenerator(System.out); 
7. ObjectMapper mapper = new ObjectMapper(); 
8. 
9. //创建节点和数据,一个ObjectNode代表一个节点对象 
10. ObjectNode node1 = factory.objectNode(); 
11. ObjectNode node2 = factory.objectNode(); 
12. node1.put("A", "a"); 
13. node1.put("B", "b"); 
14. node2.set("C", node1); 
15. 
16. // 根节点 
17. ObjectNode root = factory.objectNode(); 
18. root.put("root", "root"); 
19. root.set("children", node2); 
20. mapper.writeTree(generator, root); 
21. //输出{"root":"root","children":{"C":{"A":"a","B":"b"}}}

其他数组、list、map参考
http://www.cnblogs.com/hoojo/archive/2011/04/22/2024628.html
http://blog.youkuaiyun.com/gjb724332682/article/details/51586701

 

3、json-lib
使用的包
<!--json-lib-->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>

JSON字符串转JSONObject/JSONArray
JSONObject jsonObject = JSONObject.fromObject(jsonString/javaBean);
得到子节点
jsonObject.getString("success")
转为javaBean
JSONObject.toBean(jsonObject,JavaBean.class);
javaBean转JSON字符串
String jsonString=jsonObject.toString();

list map参照
http://www.cnblogs.com/teach/p/5791029.html


概述

Jackson框架是基于Java平台的一套数据处理工具,被称为“最好的Java Json解析器”。 
Jackson框架包含了3个核心库:streaming,databind,annotations.Jackson还包含了其它数据处理类库,此外不作说明。
Jackson版本: 1.x (目前版本从1.1~1.9)与2.x。1.x与2.x从包的命名上可以看出来,1.x的类库中,包命名以:org.codehaus.jackson.xxx开头,而2.x类库中包命令:com.fastxml.jackson.xxx开头

Jackson Home Page:https://github.com/FasterXML/jackson
Jackson Wiki:http://wiki.fasterxml.com/JacksonHome
Jackson doc: https://github.com/FasterXML/jackson-docs
Jackson Download Page:http://wiki.fasterxml.com/JacksonDownload


准备工作

本文所有程序都基于JDK1.7,依赖jackon的三个核心类库:
jackson-core-2.5.3.jar
jackson-annotations-2.5.3.jar
jackson-databind-2.5.3.jar


Jackson处理Json

Jackson提供了三种可选的Json处理方法:流式API(Streaming API) 、树模型(Tree Model)、数据绑定(Data Binding)。从使用角度来看,比较一下这三种处理Json的方式的特性:

Streaming API:是效率最高的处理方式(开销低、读写速度快,但程序编写复杂度高)
Tree Model:是最灵活的处理方式
Data Binding:是最常用的处理方式

下面我们通过例子程序分别使用DataBinding,TreeModel,Streaming的方式来创建和解析Json字符串

1.DataBinding处理Json

Jackson支持Java对象与Json之间的相互转化。java对象序列化为json字符串,json字符串也可以反序列化为相同的java对象。

(1)java对象转化成json:
Province.java
[java]   view plain  copy
  1. package com.jackson.json.databinding;  
  2.   
  3. public class Province {  
  4.     public String name;  
  5.     public int population;  
  6.     public String[] city;     
  7. }  
Country.java
[java]   view plain  copy
  1. package com.jackson.json.databinding;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Arrays;  
  5. import java.util.Date;  
  6. import java.util.HashMap;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9.   
  10. public class Country {  
  11.     // 注意:被序列化的bean的private属性字段需要创建getter方法或者属性字段应该为public  
  12.     private String country_id;  
  13.     private Date birthDate;  
  14.     private List<String> nation = new ArrayList<String>();  
  15.     private String[] lakes;  
  16.     private List<Province> provinces = new ArrayList<Province>();  
  17.     private Map<String, Integer> traffic = new HashMap<String, Integer>();  
  18.   
  19.     public Country() {  
  20.         // TODO Auto-generated constructor stub  
  21.     }  
  22.   
  23.     public Country(String countryId) {  
  24.         this.country_id = countryId;  
  25.     }  
  26.   
  27.     public String getCountry_id() {  
  28.         return country_id;  
  29.     }  
  30.   
  31.     public void setCountry_id(String country_id) {  
  32.         this.country_id = country_id;  
  33.     }  
  34.   
  35.     public Date getBirthDate() {  
  36.         return birthDate;  
  37.     }  
  38.   
  39.     public void setBirthDate(Date birthDate) {  
  40.         this.birthDate = birthDate;  
  41.     }  
  42.   
  43.     public List<String> getNation() {  
  44.         return nation;  
  45.     }  
  46.   
  47.     public void setNation(List<String> nation) {  
  48.         this.nation = nation;  
  49.     }  
  50.   
  51.     public String[] getLakes() {  
  52.         return lakes;  
  53.     }  
  54.   
  55.     public void setLakes(String[] lakes) {  
  56.         this.lakes = lakes;  
  57.     }  
  58.   
  59.     public Integer get(String key) {  
  60.         return traffic.get(key);  
  61.     }  
  62.   
  63.     public Map<String, Integer> getTraffic() {  
  64.         return traffic;  
  65.     }  
  66.   
  67.     public void setTraffic(Map<String, Integer> traffic) {  
  68.         this.traffic = traffic;  
  69.     }  
  70.   
  71.     public void addTraffic(String key, Integer value) {  
  72.         traffic.put(key, value);  
  73.     }  
  74.   
  75.     public List<Province> getProvinces() {  
  76.         return provinces;  
  77.     }  
  78.   
  79.     public void setProvinces(List<Province> provinces) {  
  80.         this.provinces = provinces;  
  81.     }  
  82.   
  83.     @Override  
  84.     public String toString() {  
  85.         return "Country [country_id=" + country_id + ", birthDate=" + birthDate  
  86.                 + ", nation=" + nation + ", lakes=" + Arrays.toString(lakes)  
  87.                 + ", province=" + provinces + ", traffic=" + traffic + "]";  
  88.     }  
  89.   
  90. }  
JavaBeanSerializeToJson.java
[java]   view plain  copy
  1. package com.jackson.json.databinding;  
  2.   
  3. import java.io.File;  
  4. import java.text.SimpleDateFormat;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. import com.fasterxml.jackson.annotation.JsonInclude.Include;  
  9. import com.fasterxml.jackson.databind.ObjectMapper;  
  10. import com.fasterxml.jackson.databind.SerializationFeature;  
  11.   
  12. public class JavaBeanSerializeToJson {  
  13.   
  14.     public static void convert() throws Exception {  
  15.         // 使用ObjectMapper来转化对象为Json  
  16.         ObjectMapper mapper = new ObjectMapper();  
  17.         // 添加功能,让时间格式更具有可读性  
  18.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");  
  19.         mapper.setDateFormat(dateFormat);  
  20.   
  21.         Country country = new Country("China");  
  22.         country.setBirthDate(dateFormat.parse("1949-10-01"));  
  23.         country.setLakes(new String[] { "Qinghai Lake""Poyang Lake",  
  24.                 "Dongting Lake""Taihu Lake" });  
  25.   
  26.         List<String> nation = new ArrayList<String>();  
  27.         nation.add("Han");  
  28.         nation.add("Meng");  
  29.         nation.add("Hui");  
  30.         nation.add("WeiWuEr");  
  31.         nation.add("Zang");  
  32.         country.setNation(nation);  
  33.   
  34.         Province province = new Province();  
  35.         province.name = "Shanxi";  
  36.         province.population = 37751200;  
  37.         Province province2 = new Province();  
  38.         province2.name = "ZheJiang";  
  39.         province2.population = 55080000;  
  40.         List<Province> provinces = new ArrayList<Province>();  
  41.         provinces.add(province);  
  42.         provinces.add(province2);  
  43.         country.setProvinces(provinces);  
  44.           
  45.         country.addTraffic("Train(KM)"112000);  
  46.         country.addTraffic("HighWay(KM)"4240000);  
  47.         // 为了使JSON视觉上的可读性,增加一行如下代码,注意,在生产中不需要这样,因为这样会增大Json的内容  
  48.         mapper.configure(SerializationFeature.INDENT_OUTPUT, true);  
  49.         // 配置mapper忽略空属性  
  50.         mapper.setSerializationInclusion(Include.NON_EMPTY);  
  51.         // 默认情况,Jackson使用Java属性字段名称作为 Json的属性名称,也可以使用Jackson annotations(注解)改变Json属性名称  
  52.         mapper.writeValue(new File("country.json"), country);  
  53.     }  
  54.   
  55.     public static void main(String[] args) throws Exception {  
  56.         convert();  
  57.     }  
  58.   
  59. }  
程序运行后生成country.json,内容如下:
[html]   view plain  copy
  1. {  
  2.   "country_id" : "China",  
  3.   "birthDate" : "1949-10-01",  
  4.   "nation" : [ "Han", "Meng", "Hui", "WeiWuEr", "Zang" ],  
  5.   "lakes" : [ "Qinghai Lake", "Poyang Lake", "Dongting Lake", "Taihu Lake" ],  
  6.   "provinces" : [ {  
  7.     "name" : "Shanxi",  
  8.     "population" : 37751200  
  9.   }, {  
  10.     "name" : "ZheJiang",  
  11.     "population" : 55080000  
  12.   } ],  
  13.   "traffic" : {  
  14.     "HighWay(KM)" : 4240000,  
  15.     "Train(KM)" : 112000  
  16.   }  
  17. }  

(2)Json字符串反序列化为java对象:
[java]   view plain  copy
  1. package com.jackson.json.databinding;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.text.SimpleDateFormat;  
  6. import java.util.Iterator;  
  7. import java.util.List;  
  8.   
  9. import com.fasterxml.jackson.core.JsonParseException;  
  10. import com.fasterxml.jackson.databind.DeserializationFeature;  
  11. import com.fasterxml.jackson.databind.JsonMappingException;  
  12. import com.fasterxml.jackson.databind.ObjectMapper;  
  13.   
  14. /** 
  15.  * 将Json字符串反序列化为Java对象 
  16.  */  
  17. public class JsonDeserializeToJava {  
  18.       
  19.     public static void main(String[] args) throws Exception {  
  20.         //ObjectMapper类用序列化与反序列化映射器  
  21.         ObjectMapper mapper = new ObjectMapper();  
  22.         File json = new File("country.json");  
  23.         //当反序列化json时,未知属性会引起的反序列化被打断,这里我们禁用未知属性打断反序列化功能,  
  24.         //因为,例如json里有10个属性,而我们的bean中只定义了2个属性,其它8个属性将被忽略  
  25.         mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);  
  26.           
  27.         //从json映射到java对象,得到country对象后就可以遍历查找,下面遍历部分内容,能说明问题就可以了  
  28.         Country country = mapper.readValue(json, Country.class);  
  29.         System.out.println("country_id:"+country.getCountry_id());  
  30.         //设置时间格式,便于阅读  
  31.         SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");  
  32.         String birthDate = dateformat.format(country.getBirthDate());  
  33.         System.out.println("birthDate:"+birthDate);  
  34.           
  35.         List<Province> provinces = country.getProvinces();  
  36.         for (Province province : provinces) {  
  37.             System.out.println("province:"+province.name + "\n" + "population:"+province.population);  
  38.         }  
  39.     }  
  40. }  
程序运行结果:
[html]   view plain  copy
  1. country_id:China  
  2. birthDate:1949-10-01  
  3. province:Shanxi  
  4. population:37751200  
  5. province:ZheJiang  
  6. population:55080000  

2.Tree Model处理Json

(1)tree model生成json:

[java]   view plain  copy
  1. package com.jackson.json.treemodel;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileWriter;  
  5.   
  6. import com.fasterxml.jackson.core.JsonFactory;  
  7. import com.fasterxml.jackson.core.JsonGenerator;  
  8. import com.fasterxml.jackson.databind.ObjectMapper;  
  9. import com.fasterxml.jackson.databind.SerializationFeature;  
  10. import com.fasterxml.jackson.databind.node.ArrayNode;  
  11. import com.fasterxml.jackson.databind.node.JsonNodeFactory;  
  12. import com.fasterxml.jackson.databind.node.ObjectNode;  
  13.   
  14. public class SerializationExampleTreeModel {  
  15.       
  16.     public static void main(String[] args) throws Exception {  
  17.         //创建一个节点工厂,为我们提供所有节点  
  18.         JsonNodeFactory factory = new JsonNodeFactory(false);  
  19.         //创建一个json factory来写tree modle为json  
  20.         JsonFactory jsonFactory = new JsonFactory();  
  21.         //创建一个json生成器  
  22.         JsonGenerator generator = jsonFactory.createGenerator(new FileWriter(new File("country2.json")));  
  23.         //注意,默认情况下对象映射器不会指定根节点,下面设根节点为country  
  24.         ObjectMapper mapper = new ObjectMapper();  
  25.         ObjectNode country = factory.objectNode();  
  26.           
  27.         country.put("country_id""China");  
  28.         country.put("birthDate""1949-10-01");  
  29.           
  30.         //在Java中,List和Array转化为json后对应的格式符号都是"obj:[]"  
  31.         ArrayNode nation = factory.arrayNode();  
  32.         nation.add("Han").add("Meng").add("Hui").add("WeiWuEr").add("Zang");  
  33.         country.set("nation", nation);  
  34.           
  35.         ArrayNode lakes = factory.arrayNode();  
  36.         lakes.add("QingHai Lake").add("Poyang Lake").add("Dongting Lake").add("Taihu Lake");  
  37.         country.set("lakes", lakes);  
  38.           
  39.         ArrayNode provinces = factory.arrayNode();  
  40.         ObjectNode province = factory.objectNode();  
  41.         ObjectNode province2 = factory.objectNode();  
  42.         province.put("name","Shanxi");  
  43.         province.put("population"37751200);  
  44.         province2.put("name","ZheJiang");  
  45.         province2.put("population"55080000);  
  46.         provinces.add(province).add(province2);  
  47.         country.set("provinces", provinces);  
  48.           
  49.         ObjectNode traffic = factory.objectNode();  
  50.         traffic.put("HighWay(KM)"4240000);  
  51.         traffic.put("Train(KM)"112000);  
  52.         country.set("traffic", traffic);  
  53.           
  54.         mapper.configure(SerializationFeature.INDENT_OUTPUT, true);  
  55.         mapper.writeTree(generator, country);  
  56.     }  
  57.   
  58. }  

程序运行生成country2.json,内容如下:

[html]   view plain  copy
  1. {"country_id":"China","birthDate":"1949-10-01","nation":["Han","Meng","Hui","WeiWuEr","Zang"],"lakes":["QingHai Lake","Poyang Lake","Dongting Lake","Taihu Lake"],"provinces":[{"name":"Shanxi","population":37751200},{"name":"ZheJiang","population":55080000}],"traffic":{"HighWay(KM)":4240000,"Train(KM)":112000}}  

(2) json字符串反序列化为tree mode

DeserializationExampleTreeModel1.java,请注意观察程序中不同的JsonNode的类型变化

[java]   view plain  copy
  1. package com.jackson.json.treemodel;  
  2.   
  3. import java.io.File;  
  4. import java.util.Iterator;  
  5.   
  6. import com.fasterxml.jackson.databind.JsonNode;  
  7. import com.fasterxml.jackson.databind.ObjectMapper;  
  8.   
  9. public class DeserializationExampleTreeModel1 {  
  10.   
  11.     public static void main(String[] args) throws Exception {  
  12.         ObjectMapper mapper = new ObjectMapper();  
  13.         // Jackson提供一个树节点被称为"JsonNode",ObjectMapper提供方法来读json作为树的JsonNode根节点  
  14.         JsonNode node = mapper.readTree(new File("country2.json"));  
  15.         // 看看根节点的类型  
  16.         System.out.println("node JsonNodeType:"+node.getNodeType());  
  17.         // 是不是一个容器  
  18.         System.out.println("node is container Node ? "+node.isContainerNode());  
  19.         // 得到所有node节点的子节点名称  
  20.         System.out.println("---------得到所有node节点的子节点名称-------------------------");  
  21.         Iterator<String> fieldNames = node.fieldNames();  
  22.         while (fieldNames.hasNext()) {  
  23.             String fieldName = fieldNames.next();  
  24.             System.out.print(fieldName+" ");  
  25.         }  
  26.         System.out.println("\n-----------------------------------------------------");  
  27.         // as.Text的作用是有值返回值,无值返回空字符串  
  28.         JsonNode country_id = node.get("country_id");  
  29.         System.out.println("country_id:"+country_id.asText() + " JsonNodeType:"+country_id.getNodeType());  
  30.           
  31.         JsonNode birthDate = node.get("birthDate");  
  32.         System.out.println("birthDate:"+birthDate.asText()+" JsonNodeType:"+birthDate.getNodeType());  
  33.           
  34.         JsonNode nation = node.get("nation");  
  35.         System.out.println("nation:"+ nation+ " JsonNodeType:"+nation.getNodeType());  
  36.           
  37.         JsonNode lakes = node.get("lakes");  
  38.         System.out.println("lakes:"+lakes+" JsonNodeType:"+lakes.getNodeType());  
  39.   
  40.         JsonNode provinces = node.get("provinces");  
  41.         System.out.println("provinces JsonNodeType:"+provinces.getNodeType());  
  42.   
  43.         boolean flag = true;  
  44.         for (JsonNode provinceElements : provinces) {  
  45.             //为了避免provinceElements多次打印,用flag控制打印,能体现provinceElements的JsonNodeType就可以了  
  46.             if(flag){  
  47.                 System.out.println("provinceElements JsonNodeType:"+provinceElements.getNodeType());  
  48.                 System.out.println("provinceElements is container node? "+provinceElements.isContainerNode());  
  49.                 flag = false;  
  50.             }  
  51.             Iterator<String> provinceElementFields = provinceElements.fieldNames();  
  52.             while (provinceElementFields.hasNext()) {  
  53.                 String fieldName = (String) provinceElementFields.next();  
  54.                 String province;  
  55.                 if ("population".equals(fieldName)) {  
  56.                     province = fieldName + ":" + provinceElements.get(fieldName).asInt();  
  57.                 }else{  
  58.                     province = fieldName + ":" + provinceElements.get(fieldName).asText();  
  59.                 }  
  60.                 System.out.println(province);  
  61.             }  
  62.         }  
  63.     }  
  64. }  

程序运行后打印结果如下:

[html]   view plain  copy
  1. node JsonNodeType:OBJECT  
  2. node is container Node ? true  
  3. ---------得到所有node节点的子节点名称-------------------------  
  4. country_id birthDate nation lakes provinces traffic   
  5. -----------------------------------------------------  
  6. country_id:China JsonNodeType:STRING  
  7. birthDate:1949-10-01 JsonNodeType:STRING  
  8. nation:["Han","Meng","Hui","WeiWuEr","Zang"] JsonNodeType:ARRAY  
  9. lakes:["QingHai Lake","Poyang Lake","Dongting Lake","Taihu Lake"] JsonNodeType:ARRAY  
  10. provinces JsonNodeType:ARRAY  
  11. provinceElements JsonNodeType:OBJECT  
  12. provinceElements is container node? true  
  13. name:Shanxi  
  14. population:37751200  
  15. name:ZheJiang  
  16. population:55080000  


在来看一下DeserializationExampleTreeModel2.java,本例中使用JsonNode.path的方法,path方法类似于DeserializationExampleTreeModel1.java中使用的get方法,

但当node不存在时,get方法返回null,而path返回MISSING类型的JsonNode

[java]   view plain  copy
  1. package com.jackson.json.treemodel;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.util.Iterator;  
  6.   
  7. import com.fasterxml.jackson.core.JsonProcessingException;  
  8. import com.fasterxml.jackson.databind.JsonNode;  
  9. import com.fasterxml.jackson.databind.ObjectMapper;  
  10.   
  11. public class DeserializationExampleTreeModle2 {  
  12.       
  13.     public static void main(String[] args) throws JsonProcessingException, IOException{  
  14.         ObjectMapper mapper = new ObjectMapper();  
  15.         JsonNode node = mapper.readTree(new File("country2.json"));  
  16.         //path方法获取JsonNode时,当对象不存在时,返回MISSING类型的JsonNode  
  17.         JsonNode missingNode = node.path("test");  
  18.         if(missingNode.isMissingNode()){  
  19.             System.out.println("JsonNodeType : " + missingNode.getNodeType());  
  20.         }  
  21.   
  22.         System.out.println("country_id:"+node.path("country_id").asText());  
  23.           
  24.         JsonNode provinces = node.path("provinces");  
  25.         for (JsonNode provinceElements : provinces) {  
  26.             Iterator<String> provincesFields = provinceElements.fieldNames();  
  27.             while (provincesFields.hasNext()) {  
  28.                 String fieldName = (String) provincesFields.next();  
  29.                 String province;  
  30.                 if("name".equals(fieldName)){  
  31.                     province = fieldName +":"+ provinceElements.path(fieldName).asText();  
  32.                 }else{  
  33.                     province = fieldName +":"+ provinceElements.path(fieldName).asInt();  
  34.                 }  
  35.                 System.out.println(province);  
  36.             }  
  37.         }  
  38.     }  
  39.   
  40. }  
程序运行打印结果:
[html]   view plain  copy
  1. JsonNodeType : MISSING  
  2. country_id:China  
  3. name:Shanxi  
  4. population:37751200  
  5. name:ZheJiang  
  6. population:55080000  

3.Stream处理Json

(1)stream生成json
[java]   view plain  copy
  1. package com.jackson.json.streaming;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileWriter;  
  5. import java.io.Exception;  
  6.   
  7. import com.fasterxml.jackson.core.JsonFactory;  
  8. import com.fasterxml.jackson.core.JsonGenerator;  
  9.   
  10. public class StreamGeneratorJson {  
  11.       
  12.     public static void main(String[] args) throws Exception {  
  13.         JsonFactory factory = new JsonFactory();  
  14.         //从JsonFactory创建一个JsonGenerator生成器的实例  
  15.         JsonGenerator generator = factory.createGenerator(new FileWriter(new File("country3.json")));  
  16.           
  17.         generator.writeStartObject();  
  18.         generator.writeFieldName("country_id");  
  19.         generator.writeString("China");  
  20.         generator.writeFieldName("provinces");  
  21.         generator.writeStartArray();  
  22.         generator.writeStartObject();  
  23.         generator.writeStringField("name""Shanxi");  
  24.         generator.writeNumberField("population"33750000);  
  25.         generator.writeEndObject();  
  26.         generator.writeEndArray();  
  27.         generator.writeEndObject();  
  28.           
  29.         generator.close();  
  30.     }  
  31.   
  32. }  
程序运行后生成country3.json文件内容:
[html]   view plain  copy
  1. {"country_id":"China","provinces":[{"name":"Shanxi","population":33750000}]}  

(2)stream解析json:
现在adgcountry3.json,我们用Streaming API的方式来解析上面的Json,并查找json中population的值。
[java]   view plain  copy
  1. package com.jackson.json.streaming;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5.   
  6. import com.fasterxml.jackson.core.JsonFactory;  
  7. import com.fasterxml.jackson.core.JsonParseException;  
  8. import com.fasterxml.jackson.core.JsonParser;  
  9. import com.fasterxml.jackson.core.JsonToken;  
  10.   
  11. /*Jackson API提供了token对每个Json对象,例如,Json开始符号“{”是token指向的第一个解析的对象, 
  12.  key:value键值对是另一个单独的对象。这个API很强大,但也需要编写大量代码。不推荐使用,平时更多的是使用DataBinding和TreeModel来处理json 
  13.  */  
  14. public class StreamParserJson {  
  15.     public static void main(String[] args) throws JsonParseException,  
  16.             IOException {  
  17.         JsonFactory factory = new JsonFactory();  
  18.         // 从JsonFactory创建JsonParser解析器的实例  
  19.         JsonParser parser = factory.createParser(new File("country3.json"));  
  20.   
  21.         while (!parser.isClosed()) {  
  22.             // 得到一个token,第一次遍历时,token指向json文件中第一个符号"{"  
  23.             JsonToken token = parser.nextToken();  
  24.             if (token == null) {  
  25.                 break;  
  26.             }  
  27.             // 我们只查找 country3.json中的"population"字段的值,能体现解析的流程就可以了  
  28.             // 当key是provinces时,我们进入provinces,查找population  
  29.             if (JsonToken.FIELD_NAME.equals(token)  
  30.                     && "provinces".equals(parser.getCurrentName())) {  
  31.                 token = parser.nextToken();  
  32.                 if (!JsonToken.START_ARRAY.equals(token)) {  
  33.                     break;  
  34.                 }  
  35.                 // 此时,token指向的应该是"{"  
  36.                 token = parser.nextToken();  
  37.                 if (!JsonToken.START_OBJECT.equals(token)) {  
  38.                     break;  
  39.                 }  
  40.                 while (true) {  
  41.                     token = parser.nextToken();  
  42.                     if (token == null) {  
  43.                         break;  
  44.                     }  
  45.                     if (JsonToken.FIELD_NAME.equals(token)  
  46.                             && "population".equals(parser.getCurrentName())) {  
  47.                         token = parser.nextToken();  
  48.                         System.out.println(parser.getCurrentName() + " : "  
  49.                                 + parser.getIntValue());  
  50.                     }  
  51.                 }  
  52.             }  
  53.         }  
  54.     }  
  55.   
  56. }  
程序运行后,在控制台打印结果如下:
[html]   view plain  copy
  1. population : 33750000  

总结

上面的例子中,分别用3种方式处理Json,我的体会大致如下:

Stream API方式是开销最低、效率最高,但编写代码复杂度也最高,在生成Json时,需要逐步编写符号和字段拼接json,在解析Json时,需要根据token指向也查找json值,生成和解析json都不是很方便,代码可读性也很低。
Databinding处理Json是最常用的json处理方式,生成json时,创建相关的java对象,并根据json内容结构把java对象组装起来,最后调用writeValue方法即可生成json,
解析时,就更简单了,直接把json映射到相关的java对象,然后就可以遍历java对象来获取值了。
TreeModel处理Json,是以树型结构来生成和解析json,生成json时,根据json内容结构,我们创建不同类型的节点对象,组装这些节点生成json。解析json时,它不需要绑定json到java bean,根据json结构,使用path或get方法轻松查找内容。

学习参考: http://www.cnblogs.com/lee0oo0/articles/2652528.html

概述

jackson解析json例子

准备工作

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

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

Example

下面的例子是基于Jackson 2.x版本的树模型的Json解析。

要解析的Json字符串:

[plain]   view plain  copy
  1. String data = {  
  2.             "type":2,"range":1,"start":1368417600,"end":1368547140,"cityName":"天津",  
  3.             "companyIds":["12000001"],  
  4.             "companyNames":["天津"],  
  5.             "12000001":{  
  6.                 "data":[47947,48328,48573,48520],  
  7.                 "timestamps":[1368417600,1368417900,1368418200,1368418500]  
  8.             }  
  9.     }  

示例代码:

[java]   view plain  copy
  1. package com.cennavi.dqe.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.text.SimpleDateFormat;  
  5. import java.util.Date;  
  6. import java.util.TimeZone;  
  7.   
  8. import com.fasterxml.jackson.core.JsonProcessingException;  
  9. import com.fasterxml.jackson.databind.JsonNode;  
  10. import com.fasterxml.jackson.databind.ObjectMapper;  
  11.   
  12. public class ParseJsonTest {  
  13.   
  14.     /** 
  15.      * @param args 
  16.      */  
  17.     public static void main(String[] args) {  
  18.         String data = "{\"type\":2,\"range\":1,\"start\":1368417600,\"end\":1368547140,"  
  19.                 + "\"cityName\":\"天津\",\"companyIds\":[\"12000001\"],\"companyNames\":[\"天津\"],"  
  20.                 + "\"12000001\":{\"data\":[47947,48328,48573,48520],"  
  21.                 + "\"timestamps\":[1368417600,1368417900,1368418200,1368418500]}}";  
  22.         String data2 = parseJson(data);  
  23.         System.out.println(data2);  
  24.     }  
  25.   
  26.     public static String parseJson(String data) {  
  27.         // 用来展现解析Json得到的值  
  28.         StringBuffer buf = new StringBuffer();  
  29.         try {  
  30.             ObjectMapper mapper = new ObjectMapper();  
  31.             JsonNode rootNode = mapper.readTree(data); // 读取Json  
  32.             // rootNode.path("xx")返回的还是一个JsonNode对象,调用该JsonNode的相应方法,得到键对应的值  
  33.             int type = rootNode.path("type").asInt();  
  34.             int range = rootNode.path("range").asInt();  
  35.             long start = rootNode.path("start").asLong();  
  36.             long end = rootNode.path("end").asLong();  
  37.             String cityName = rootNode.path("cityName").asText();  
  38.   
  39.             // 转换时间格式  
  40.             SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");  
  41.             sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));  
  42.   
  43.             String str = "类型(type):" + type + "\r\n" + "范围(range):" + range  
  44.                     + "\r\n" + "开始时间(start):"  
  45.                     + sdf.format(new Date(start * 1000)) + "\r\n"  
  46.                     + "结束时间(end):" + sdf.format(new Date(end * 1000)) + "\r\n"  
  47.                     + "城市名称(cityName):" + cityName;  
  48.             buf.append(str);  
  49.             // 得到companyIds的JsonNode对象  
  50.             JsonNode companyIds = rootNode.path("companyIds");  
  51.             JsonNode companyNames = rootNode.path("companyNames");  
  52.   
  53.             // 遍历companyIds中的内容  
  54.             for (int i = 0; i < companyIds.size(); i++) {  
  55.                 String companyId = companyIds.get(i).asText();  
  56.                 // 本例解析的Json字符串中companyIds与companyNames的长度是相同的,所有直接遍历companyNames  
  57.                 String companyName = companyNames.get(i).asText();  
  58.                 // companyId的值:12000001,对应Json串中的  
  59.                 // "12000001":{"data":[...],"timestamps":[....]}  
  60.                 JsonNode infoNode = rootNode.path(companyId);  
  61.                 // 得到"12000001":{"data":[...],"timestamps":[....]}中的data和timestamps的JsonNode对象  
  62.                 JsonNode dataNode = infoNode.path("data");  
  63.                 JsonNode timestampsNode = infoNode.path("timestamps");  
  64.                 // 遍历data和timestamps 本例中data.size与timestamps.size是相等的  
  65.   
  66.                 buf.append("\r\n{\r\n  公司ID(companyId):" + companyId  
  67.                         + "\r\n  公司名称(companyName):" + companyName + "\r\n"  
  68.                         + " data:");  
  69.                 for (int j = 0; j < dataNode.size(); j++) {  
  70.                     long dataValue = dataNode.get(j).asLong();  
  71.                     buf.append(dataValue + ",");  
  72.                 }  
  73.                 buf.append("\r\n time:");  
  74.                 for (int k = 0; k < timestampsNode.size(); k++) {  
  75.                     long timeValue = timestampsNode.get(k).asLong();  
  76.                     buf.append(sdf.format(new Date(timeValue * 1000)) + ",");  
  77.                 }  
  78.                 buf.append("\r\n}\r\n");  
  79.             }  
  80.         } catch (JsonProcessingException e) {  
  81.             e.printStackTrace();  
  82.         } catch (IOException e) {  
  83.             // TODO 自动生成的 catch 块  
  84.             e.printStackTrace();  
  85.         }  
  86.         return buf.toString();  
  87.     }  
  88.   
  89. }  

测试结果:

[java]   view plain  copy
  1. 类型(type):2  
  2. 范围(range):1  
  3. 开始时间(start):201305131200  
  4. 结束时间(end):201305142359  
  5. 城市名称(cityName):天津  
  6. {  
  7.   公司ID(companyId):12000001  
  8.   公司名称(companyName):天津  
  9.   data:47947,48328,48573,48520,  
  10.   time:201305131200,201305131205,201305131210,201305131215  

概述

使用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
  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
  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
  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
  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()+"\t");  
  15.         System.out.print("headquarters:"+company.getHeadquarters()+"\t");  
  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()+"\t");  
  22.             System.out.print("employee_number:" + department.getPm()+"\t");  
  23.             //Department中未定义的字段product,employee_number  
  24.             System.out.print("product:"+department.get("product")+"\t");   
  25.             System.out.println("projectManager:"+department.get("employee_number"));  
  26.         }  
  27.     }  
  28.   
  29. }  

程序运行控制台打印结果如下:
[html]   view plain  copy
  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
  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
  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
  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
  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
  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
  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
  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
  1. Zoo [name=SH Wild Park, city=ShangHaianimals=[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
  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
  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之间的相互转化。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值