概述

Jackson框架是基于Java平台的一套数据处理工具,被称为“最好的JavaJson解析器”。 

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
  1. package com.jackson.json.databinding;
  2. public class Province {
  3. public String name;
  4. public int population;
  5. public String[] city;
  6. }
package com.jackson.json.databinding;

public class Province {

public String name;

public int population;

public String[] city;

}
Country.java
  1. package com.jackson.json.databinding;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.Date;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. public class Country {
  9. // 注意:被序列化的bean的private属性字段需要创建getter方法或者属性字段应该为public
  10. private String country_id;
  11. private Date birthDate;
  12. private List<String> nation = new ArrayList<String>();
  13. private String[] lakes;
  14. private List<Province> provinces = new ArrayList<Province>();
  15. private Map<String, Integer> traffic = new HashMap<String, Integer>();
  16. public Country() {
  17. // TODO Auto-generated constructor stub
  18. }
  19. public Country(String countryId) {
  20. this.country_id = countryId;
  21. }
  22. public String getCountry_id() {
  23. return country_id;
  24. }
  25. public void setCountry_id(String country_id) {
  26. this.country_id = country_id;
  27. }
  28. public Date getBirthDate() {
  29. return birthDate;
  30. }
  31. public void setBirthDate(Date birthDate) {
  32. this.birthDate = birthDate;
  33. }
  34. public List<String> getNation() {
  35. return nation;
  36. }
  37. public void setNation(List<String> nation) {
  38. this.nation = nation;
  39. }
  40. public String[] getLakes() {
  41. return lakes;
  42. }
  43. public void setLakes(String[] lakes) {
  44. this.lakes = lakes;
  45. }
  46. public Integer get(String key) {
  47. return traffic.get(key);
  48. }
  49. public Map<String, Integer> getTraffic() {
  50. return traffic;
  51. }
  52. public void setTraffic(Map<String, Integer> traffic) {
  53. this.traffic = traffic;
  54. }
  55. public void addTraffic(String key, Integer value) {
  56. traffic.put(key, value);
  57. }
  58. public List<Province> getProvinces() {
  59. return provinces;
  60. }
  61. public void setProvinces(List<Province> provinces) {
  62. this.provinces = provinces;
  63. }
  64. @Override
  65. public String toString() {
  66. return “Country [country_id=” + country_id + “, birthDate=” + birthDate
  67. + ”, nation=” + nation + “, lakes=” + Arrays.toString(lakes)
  68. + ”, province=” + provinces + “, traffic=” + traffic + “]”;
  69. }
  70. }
package com.jackson.json.databinding;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map; public class Country {

// 注意:被序列化的bean的private属性字段需要创建getter方法或者属性字段应该为public

private String country_id;

private Date birthDate;

private List<String> nation = new ArrayList<String>();

private String[] lakes;

private List<Province> provinces = new ArrayList<Province>();

private Map<String, Integer> traffic = new HashMap<String, Integer>();
public Country() {
// TODO Auto-generated constructor stub
} public Country(String countryId) {
this.country_id = countryId;
} public String getCountry_id() {
return country_id;
} public void setCountry_id(String country_id) {
this.country_id = country_id;
} public Date getBirthDate() {
return birthDate;
} public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
} public List&lt;String&gt; getNation() {
return nation;
} public void setNation(List&lt;String&gt; nation) {
this.nation = nation;
} public String[] getLakes() {
return lakes;
} public void setLakes(String[] lakes) {
this.lakes = lakes;
} public Integer get(String key) {
return traffic.get(key);
} public Map&lt;String, Integer&gt; getTraffic() {
return traffic;
} public void setTraffic(Map&lt;String, Integer&gt; traffic) {
this.traffic = traffic;
} public void addTraffic(String key, Integer value) {
traffic.put(key, value);
} public List&lt;Province&gt; getProvinces() {
return provinces;
} public void setProvinces(List&lt;Province&gt; provinces) {
this.provinces = provinces;
} @Override
public String toString() {
return "Country [country_id=" + country_id + ", birthDate=" + birthDate
+ ", nation=" + nation + ", lakes=" + Arrays.toString(lakes)
+ ", province=" + provinces + ", traffic=" + traffic + "]";
}

}

JavaBeanSerializeToJson.java

  1. package com.jackson.json.databinding;
  2. import java.io.File;
  3. import java.text.SimpleDateFormat;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import com.fasterxml.jackson.annotation.JsonInclude.Include;
  7. import com.fasterxml.jackson.databind.ObjectMapper;
  8. import com.fasterxml.jackson.databind.SerializationFeature;
  9. public class JavaBeanSerializeToJson {
  10. public static void convert() throws Exception {
  11. // 使用ObjectMapper来转化对象为Json
  12. ObjectMapper mapper = new ObjectMapper();
  13. // 添加功能,让时间格式更具有可读性
  14. SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);
  15. mapper.setDateFormat(dateFormat);
  16. Country country = new Country(“China”);
  17. country.setBirthDate(dateFormat.parse(”1949-10-01”));
  18. country.setLakes(new String[] { “Qinghai Lake”, “Poyang Lake”,
  19. ”Dongting Lake”, “Taihu Lake” });
  20. List<String> nation = new ArrayList<String>();
  21. nation.add(”Han”);
  22. nation.add(”Meng”);
  23. nation.add(”Hui”);
  24. nation.add(”WeiWuEr”);
  25. nation.add(”Zang”);
  26. country.setNation(nation);
  27. Province province = new Province();
  28. province.name = ”Shanxi”;
  29. province.population = 37751200;
  30. Province province2 = new Province();
  31. province2.name = ”ZheJiang”;
  32. province2.population = 55080000;
  33. List<Province> provinces = new ArrayList<Province>();
  34. provinces.add(province);
  35. provinces.add(province2);
  36. country.setProvinces(provinces);
  37. country.addTraffic(”Train(KM)”, 112000);
  38. country.addTraffic(”HighWay(KM)”, 4240000);
  39. // 为了使JSON视觉上的可读性,增加一行如下代码,注意,在生产中不需要这样,因为这样会增大Json的内容
  40. mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
  41. // 配置mapper忽略空属性
  42. mapper.setSerializationInclusion(Include.NON_EMPTY);
  43. // 默认情况,Jackson使用Java属性字段名称作为 Json的属性名称,也可以使用Jackson annotations(注解)改变Json属性名称
  44. mapper.writeValue(new File(“country.json”), country);
  45. }
  46. public static void main(String[] args) throws Exception {
  47. convert();
  48. }
  49. }
package com.jackson.json.databinding;

import java.io.File;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude.Include;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.SerializationFeature; public class JavaBeanSerializeToJson {
public static void convert() throws Exception {
// 使用ObjectMapper来转化对象为Json
ObjectMapper mapper = new ObjectMapper();
// 添加功能,让时间格式更具有可读性
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
mapper.setDateFormat(dateFormat); Country country = new Country("China");
country.setBirthDate(dateFormat.parse("1949-10-01"));
country.setLakes(new String[] { "Qinghai Lake", "Poyang Lake",
"Dongting Lake", "Taihu Lake" }); List&lt;String&gt; nation = new ArrayList&lt;String&gt;();
nation.add("Han");
nation.add("Meng");
nation.add("Hui");
nation.add("WeiWuEr");
nation.add("Zang");
country.setNation(nation); Province province = new Province();
province.name = "Shanxi";
province.population = 37751200;
Province province2 = new Province();
province2.name = "ZheJiang";
province2.population = 55080000;
List&lt;Province&gt; provinces = new ArrayList&lt;Province&gt;();
provinces.add(province);
provinces.add(province2);
country.setProvinces(provinces); country.addTraffic("Train(KM)", 112000);
country.addTraffic("HighWay(KM)", 4240000);
// 为了使JSON视觉上的可读性,增加一行如下代码,注意,在生产中不需要这样,因为这样会增大Json的内容
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
// 配置mapper忽略空属性
mapper.setSerializationInclusion(Include.NON_EMPTY);
// 默认情况,Jackson使用Java属性字段名称作为 Json的属性名称,也可以使用Jackson annotations(注解)改变Json属性名称
mapper.writeValue(new File("country.json"), country);
} public static void main(String[] args) throws Exception {
convert();
}

}

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

import java.io.File;

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.Iterator;

import java.util.List; import com.fasterxml.jackson.core.JsonParseException;

import com.fasterxml.jackson.databind.DeserializationFeature;

import com.fasterxml.jackson.databind.JsonMappingException;

import com.fasterxml.jackson.databind.ObjectMapper; /**
  • 将Json字符串反序列化为Java对象

    */

    public class JsonDeserializeToJava { public static void main(String[] args) throws Exception {

    //ObjectMapper类用序列化与反序列化映射器

    ObjectMapper mapper = new ObjectMapper();

    File json = new File("country.json");

    //当反序列化json时,未知属性会引起的反序列化被打断,这里我们禁用未知属性打断反序列化功能,

    //因为,例如json里有10个属性,而我们的bean中只定义了2个属性,其它8个属性将被忽略

    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
     //从json映射到java对象,得到country对象后就可以遍历查找,下面遍历部分内容,能说明问题就可以了
    Country country = mapper.readValue(json, Country.class);
    System.out.println("country_id:"+country.getCountry_id());
    //设置时间格式,便于阅读
    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
    String birthDate = dateformat.format(country.getBirthDate());
    System.out.println("birthDate:"+birthDate); List&lt;Province&gt; provinces = country.getProvinces();
    for (Province province : provinces) {
    System.out.println("province:"+province.name + "\n" + "population:"+province.population);
    }

    }

    }

程序运行结果:
  1. country_id:China
  2. birthDate:1949-10-01
  3. province:Shanxi
  4. population:37751200
  5. province:ZheJiang
  6. population:55080000
country_id:China
birthDate:1949-10-01
province:Shanxi
population:37751200
province:ZheJiang
population:55080000

2.Tree Model处理Json

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

import java.io.File;

import java.io.FileWriter; import com.fasterxml.jackson.core.JsonFactory;

import com.fasterxml.jackson.core.JsonGenerator;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.SerializationFeature;

import com.fasterxml.jackson.databind.node.ArrayNode;

import com.fasterxml.jackson.databind.node.JsonNodeFactory;

import com.fasterxml.jackson.databind.node.ObjectNode; public class SerializationExampleTreeModel {
public static void main(String[] args) throws Exception {
//创建一个节点工厂,为我们提供所有节点
JsonNodeFactory factory = new JsonNodeFactory(false);
//创建一个json factory来写tree modle为json
JsonFactory jsonFactory = new JsonFactory();
//创建一个json生成器
JsonGenerator generator = jsonFactory.createGenerator(new FileWriter(new File("country2.json")));
//注意,默认情况下对象映射器不会指定根节点,下面设根节点为country
ObjectMapper mapper = new ObjectMapper();
ObjectNode country = factory.objectNode(); country.put("country_id", "China");
country.put("birthDate", "1949-10-01"); //在Java中,List和Array转化为json后对应的格式符号都是"obj:[]"
ArrayNode nation = factory.arrayNode();
nation.add("Han").add("Meng").add("Hui").add("WeiWuEr").add("Zang");
country.set("nation", nation); ArrayNode lakes = factory.arrayNode();
lakes.add("QingHai Lake").add("Poyang Lake").add("Dongting Lake").add("Taihu Lake");
country.set("lakes", lakes); ArrayNode provinces = factory.arrayNode();
ObjectNode province = factory.objectNode();
ObjectNode province2 = factory.objectNode();
province.put("name","Shanxi");
province.put("population", 37751200);
province2.put("name","ZheJiang");
province2.put("population", 55080000);
provinces.add(province).add(province2);
country.set("provinces", provinces); ObjectNode traffic = factory.objectNode();
traffic.put("HighWay(KM)", 4240000);
traffic.put("Train(KM)", 112000);
country.set("traffic", traffic); mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.writeTree(generator, country);
}

}

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

  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}}
{"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的类型变化

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

import java.io.File;

import java.util.Iterator; import com.fasterxml.jackson.databind.JsonNode;

import com.fasterxml.jackson.databind.ObjectMapper; public class DeserializationExampleTreeModel1 {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// Jackson提供一个树节点被称为"JsonNode",ObjectMapper提供方法来读json作为树的JsonNode根节点
JsonNode node = mapper.readTree(new File("country2.json"));
// 看看根节点的类型
System.out.println("node JsonNodeType:"+node.getNodeType());
// 是不是一个容器
System.out.println("node is container Node ? "+node.isContainerNode());
// 得到所有node节点的子节点名称
System.out.println("---------得到所有node节点的子节点名称-------------------------");
Iterator&lt;String&gt; fieldNames = node.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
System.out.print(fieldName+" ");
}
System.out.println("\n-----------------------------------------------------");
// as.Text的作用是有值返回值,无值返回空字符串
JsonNode country_id = node.get("country_id");
System.out.println("country_id:"+country_id.asText() + " JsonNodeType:"+country_id.getNodeType()); JsonNode birthDate = node.get("birthDate");
System.out.println("birthDate:"+birthDate.asText()+" JsonNodeType:"+birthDate.getNodeType()); JsonNode nation = node.get("nation");
System.out.println("nation:"+ nation+ " JsonNodeType:"+nation.getNodeType()); JsonNode lakes = node.get("lakes");
System.out.println("lakes:"+lakes+" JsonNodeType:"+lakes.getNodeType()); JsonNode provinces = node.get("provinces");
System.out.println("provinces JsonNodeType:"+provinces.getNodeType()); boolean flag = true;
for (JsonNode provinceElements : provinces) {
//为了避免provinceElements多次打印,用flag控制打印,能体现provinceElements的JsonNodeType就可以了
if(flag){
System.out.println("provinceElements JsonNodeType:"+provinceElements.getNodeType());
System.out.println("provinceElements is container node? "+provinceElements.isContainerNode());
flag = false;
}
Iterator&lt;String&gt; provinceElementFields = provinceElements.fieldNames();
while (provinceElementFields.hasNext()) {
String fieldName = (String) provinceElementFields.next();
String province;
if ("population".equals(fieldName)) {
province = fieldName + ":" + provinceElements.get(fieldName).asInt();
}else{
province = fieldName + ":" + provinceElements.get(fieldName).asText();
}
System.out.println(province);
}
}
}

}

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

  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
node JsonNodeType:OBJECT
node is container Node ? true
---------得到所有node节点的子节点名称-------------------------

country_id birthDate nation lakes provinces traffic

country_id:China JsonNodeType:STRING

birthDate:1949-10-01 JsonNodeType:STRING

nation:["Han","Meng","Hui","WeiWuEr","Zang"] JsonNodeType:ARRAY

lakes:["QingHai Lake","Poyang Lake","Dongting Lake","Taihu Lake"] JsonNodeType:ARRAY

provinces JsonNodeType:ARRAY

provinceElements JsonNodeType:OBJECT

provinceElements is container node? true

name:Shanxi

population:37751200

name:ZheJiang

population:55080000

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

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

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

import java.io.File;

import java.io.IOException;

import java.util.Iterator; import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.JsonNode;

import com.fasterxml.jackson.databind.ObjectMapper; public class DeserializationExampleTreeModle2 {
public static void main(String[] args) throws JsonProcessingException, IOException{
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(new File("country2.json"));
//path方法获取JsonNode时,当对象不存在时,返回MISSING类型的JsonNode
JsonNode missingNode = node.path("test");
if(missingNode.isMissingNode()){
System.out.println("JsonNodeType : " + missingNode.getNodeType());
} System.out.println("country_id:"+node.path("country_id").asText()); JsonNode provinces = node.path("provinces");
for (JsonNode provinceElements : provinces) {
Iterator&lt;String&gt; provincesFields = provinceElements.fieldNames();
while (provincesFields.hasNext()) {
String fieldName = (String) provincesFields.next();
String province;
if("name".equals(fieldName)){
province = fieldName +":"+ provinceElements.path(fieldName).asText();
}else{
province = fieldName +":"+ provinceElements.path(fieldName).asInt();
}
System.out.println(province);
}
}
}

}

程序运行打印结果:

  1. JsonNodeType : MISSING  
  2. country_id:China  
  3. name:Shanxi  
  4. population:37751200  
  5. name:ZheJiang  
  6. population:55080000  
JsonNodeType : MISSING

country_id:China

name:Shanxi

population:37751200

name:ZheJiang

population:55080000

3.Stream处理Json

(1)stream生成json
  1. package com.jackson.json.streaming;
  2. import java.io.File;
  3. import java.io.FileWriter;
  4. import java.io.Exception;
  5. import com.fasterxml.jackson.core.JsonFactory;
  6. import com.fasterxml.jackson.core.JsonGenerator;
  7. public class StreamGeneratorJson {
  8. public static void main(String[] args) throws Exception {
  9. JsonFactory factory = new JsonFactory();
  10. //从JsonFactory创建一个JsonGenerator生成器的实例
  11. JsonGenerator generator = factory.createGenerator(new FileWriter(new File(“country3.json”)));
  12. generator.writeStartObject();
  13. generator.writeFieldName(”country_id”);
  14. generator.writeString(”China”);
  15. generator.writeFieldName(”provinces”);
  16. generator.writeStartArray();
  17. generator.writeStartObject();
  18. generator.writeStringField(”name”, “Shanxi”);
  19. generator.writeNumberField(”population”, 33750000);
  20. generator.writeEndObject();
  21. generator.writeEndArray();
  22. generator.writeEndObject();
  23. generator.close();
  24. }
  25. }
package com.jackson.json.streaming;

import java.io.File;

import java.io.FileWriter;

import java.io.Exception; import com.fasterxml.jackson.core.JsonFactory;

import com.fasterxml.jackson.core.JsonGenerator; public class StreamGeneratorJson {
public static void main(String[] args) throws Exception {
JsonFactory factory = new JsonFactory();
//从JsonFactory创建一个JsonGenerator生成器的实例
JsonGenerator generator = factory.createGenerator(new FileWriter(new File("country3.json"))); generator.writeStartObject();
generator.writeFieldName("country_id");
generator.writeString("China");
generator.writeFieldName("provinces");
generator.writeStartArray();
generator.writeStartObject();
generator.writeStringField("name", "Shanxi");
generator.writeNumberField("population", 33750000);
generator.writeEndObject();
generator.writeEndArray();
generator.writeEndObject(); generator.close();
}

}

程序运行后生成country3.json文件内容:

  1. {“country_id”:”China”,”provinces”:[{“name”:”Shanxi”,”population”:33750000}]}
{"country_id":"China","provinces":[{"name":"Shanxi","population":33750000}]}

(2)stream解析json:

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

import java.io.File;

import java.io.IOException; import com.fasterxml.jackson.core.JsonFactory;

import com.fasterxml.jackson.core.JsonParseException;

import com.fasterxml.jackson.core.JsonParser;

import com.fasterxml.jackson.core.JsonToken; /*Jackson API提供了token对每个Json对象,例如,Json开始符号“{”是token指向的第一个解析的对象,

key:value键值对是另一个单独的对象。这个API很强大,但也需要编写大量代码。不推荐使用,平时更多的是使用DataBinding和TreeModel来处理json

*/

public class StreamParserJson {

public static void main(String[] args) throws JsonParseException,

IOException {

JsonFactory factory = new JsonFactory();

// 从JsonFactory创建JsonParser解析器的实例

JsonParser parser = factory.createParser(new File("country3.json"));
    while (!parser.isClosed()) {
// 得到一个token,第一次遍历时,token指向json文件中第一个符号"{"
JsonToken token = parser.nextToken();
if (token == null) {
break;
}
// 我们只查找 country3.json中的"population"字段的值,能体现解析的流程就可以了
// 当key是provinces时,我们进入provinces,查找population
if (JsonToken.FIELD_NAME.equals(token)
&amp;&amp; "provinces".equals(parser.getCurrentName())) {
token = parser.nextToken();
if (!JsonToken.START_ARRAY.equals(token)) {
break;
}
// 此时,token指向的应该是"{"
token = parser.nextToken();
if (!JsonToken.START_OBJECT.equals(token)) {
break;
}
while (true) {
token = parser.nextToken();
if (token == null) {
break;
}
if (JsonToken.FIELD_NAME.equals(token)
&amp;&amp; "population".equals(parser.getCurrentName())) {
token = parser.nextToken();
System.out.println(parser.getCurrentName() + " : "
+ parser.getIntValue());
}
}
}
}
}

}

程序运行后,在控制台打印结果如下:
  1. population : 33750000
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 fasterxml学习的更多相关文章

  1. Jackson fasterxml跟codehaus的区别 (fasterxml vs. codehaus) -- 转载

    Jackson fasterxml和codehaus的区别: 他们是Jackson的两大分支.也是两个版本的不同包名.Jackson从2.0开始改用新的包名fasterxml:1.x版本的包名是cod ...

  2. Jackson:fasterxml和codehaus的区别

    Jackson fasterxml和codehaus的区别: 它们是jackson的两个分支.也是两个版本的不同包名.jackson从2.0开始改用新的包名fasterxml:1.x版本的包名是cod ...

  3. Jackson注解学习参考(转)

    转:http://wong-john.iteye.com/blog/1753402 以下内容摘录.翻译自https://github.com/FasterXML/jackson-annotations ...

  4. jackson 注脚学习参考

    (1)初级我们从几个简单的使用场景开始:重命名属性,忽略属性,以及修改属性所使用的类型.注意:下面的例子仅仅显示了成员属性(field properties),注解同样也可以用在成员方法(getter ...

  5. Java中常见的json序列化类库 - Jackson

    Jackson 介绍 Jackson框架是基于Java平台的一套数据处理工具,被称为"最好的Java Json解析器". Jackson框架包含了3个核心库:streaming,d ...

  6. Jackson学习笔记(详细)

    学习地址:http://tutorials.jenkov.com/java-json/index.html github地址:https://github.com/FasterXML/jackson ...

  7. 【mmall】Jackson相关知识点

    Jackson fasterxml和codehaus的区别 (fasterxml vs. codehaus) http://blog.csdn.net/clementad/article/detail ...

  8. 开源工具-Json 解析器 Jackson 的使用

    Json已经成为当前服务器与 WEB 应用之间数据传输的公认标准.Java 中常见的 Json 类库有 Gson.JSON-lib 和 Jackson 等.相比于其他的解析工具,Jackson 简单易 ...

  9. json-lib与Jackson的区别和用法分析

    一.Jackson概述 1.jackson包和版本 Jackson fasterxml和codehaus的区别: 他们是Jackson的两大分支.也是两个版本的不同包名.Jackson从2.0开始改用 ...

随机推荐

  1. [寒江孤叶丶的Cocos2d-x之旅_36]用LUA实现UTF8的字符串基本操作 UTF8字符串长度,UTF8字符串剪裁等

    原创文章,欢迎转载,转载请注明:文章来自[寒江孤叶丶的Cocos2d-x之旅系列] 博客地址:http://blog.csdn.net/qq446569365 一个用于UTF8字符串操作的类.功能比較 ...

  2. Dcloud课程7 单例模式一般用在什么场景

    Dcloud课程7 单例模式一般用在什么场景 一.总结 一句话总结:连接数据库,这样就保证了和数据之间只有一个连接,从而能够不占用多余资源,这样就极大的减少了资源浪费,减少了mysql或者说服务器压力 ...

  3. amazeui学习笔记--css(基本样式)--样式统一Normalize

    amazeui学习笔记--css(基本样式)--样式统一Normalize 一.总结 1.统一浏览器默认样式: Amaze UI 也使用了 normalize.css,就是让不同浏览器显示相同的样式 ...

  4. arduino串口输出问题

  5. 关于js盒子模型的知识梳理

    盒子模型 JS盒子模型中的13个常用属性: clientWidth/clientHeight:可视区域的宽高,宽高+PADDING组成 clientTop/clientLeft:上边框和左边框的宽度 ...

  6. 网站图标——favicon

    首先推荐一个网站图标在线制作工具favicon: 插入图标只需在head中间加入以下代码: <link rel="icon" href="img/favicon.i ...

  7. PHP与Linux进程间的通信

    进程间通信预计是公司考察应届毕业生的必考点(嵌入式行业).当然非常多公司考的是算法. 不查阅资料,我脑子里能想到的 [1] 管道, (有名.无名) [2] 父子进程 [3] System V (消息队 ...

  8. 微信浏览器跳转外部浏览器 app下载

    这个是摘抄的,具体抄的哪里我忘记了,作为记录 2019年5月14日 现在这个好像也不好用了,微信又提示建议下载qq浏览器什么的,显示一个红色感叹号,让用户产生怀疑,很鄙视tx error_report ...

  9. 【例题 6-3 UVA - 442】Matrix Chain Multiplication

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用栈来处理一下表达式就好. 因为括号是一定匹配的.所以简单很多. ab x bc会做abc次乘法. [代码] #include< ...

  10. layui是什么

    layui是什么 一.总结 一句话总结:初步看起来比amazeui好看一点点.移动端显示看起来效果真心不错.还有即时聊天那个组件下载,感觉真心不错,可以多去看看. 二.Layui 1.简介 经典模块化 ...