概述
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開頭html
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/JacksonDownloadjava
準備工做
本文全部程序都基於JDK1.7,依賴jackon的三個核心類庫:
jackson-core-2.5.3.jar
jackson-annotations-2.5.3.jar
jackson-databind-2.5.3.jarnode
Jackson處理Json
Jackson提供了三種可選的Json處理方法:流式API(Streaming API) 、樹模型(Tree Model)、數據綁定(Data Binding)。從使用角度來看,比較一下這三種處理Json的方式的特性:git
Streaming API:是效率最高的處理方式(開銷低、讀寫速度快,但程序編寫複雜度高)
Tree Model:是最靈活的處理方式
Data Binding:是最經常使用的處理方式github
下面咱們經過例子程序分別使用DataBinding,TreeModel,Streaming的方式來建立和解析Json字符串json
1.DataBinding處理Json
Jackson支持Java對象與Json之間的相互轉化。java對象序列化爲json字符串,json字符串也能夠反序列化爲相同的java對象。
(1)java對象轉化成json:
Province.java
- package com.jackson.json.databinding;
-
- public class Province {
- public String name;
- public int population;
- public String[] city;
- }
Country.java
- 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 {
-
- 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() {
-
- }
-
- 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<String> getNation() {
- return nation;
- }
-
- public void setNation(List<String> 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<String, Integer> getTraffic() {
- return traffic;
- }
-
- public void setTraffic(Map<String, Integer> traffic) {
- this.traffic = traffic;
- }
-
- public void addTraffic(String key, Integer value) {
- traffic.put(key, value);
- }
-
- public List<Province> getProvinces() {
- return provinces;
- }
-
- public void setProvinces(List<Province> 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
- 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 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<String> nation = new ArrayList<String>();
- 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<Province> provinces = new ArrayList<Province>();
- provinces.add(province);
- provinces.add(province2);
- country.setProvinces(provinces);
-
- country.addTraffic("Train(KM)", 112000);
- country.addTraffic("HighWay(KM)", 4240000);
-
- mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
-
- mapper.setSerializationInclusion(Include.NON_EMPTY);
-
- mapper.writeValue(new File("country.json"), country);
- }
-
- public static void main(String[] args) throws Exception {
- convert();
- }
-
- }
程序運行後生成country.json,內容以下:
- {
- "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對象:
- 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;
-
- public class JsonDeserializeToJava {
-
- public static void main(String[] args) throws Exception {
-
- ObjectMapper mapper = new ObjectMapper();
- File json = new File("country.json");
-
-
- mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
-
-
- 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<Province> provinces = country.getProvinces();
- for (Province province : provinces) {
- System.out.println("province:"+province.name + "\n" + "population:"+province.population);
- }
- }
- }
程序運行結果:
- country_id:China
- birthDate:1949-10-01
- province:Shanxi
- population:37751200
- province:ZheJiang
- population:55080000
2.Tree Model處理Json
(1)tree model生成json:app
- 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);
-
- JsonFactory jsonFactory = new JsonFactory();
-
- JsonGenerator generator = jsonFactory.createGenerator(new FileWriter(new File("country2.json")));
-
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode country = factory.objectNode();
-
- country.put("country_id", "China");
- country.put("birthDate", "1949-10-01");
-
-
- 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,內容以下:框架
- {"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 modeide
DeserializationExampleTreeModel1.java,請注意觀察程序中不一樣的JsonNode的類型變化工具
- 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();
-
- JsonNode node = mapper.readTree(new File("country2.json"));
-
- System.out.println("node JsonNodeType:"+node.getNodeType());
-
- System.out.println("node is container Node ? "+node.isContainerNode());
-
- System.out.println("---------獲得全部node節點的子節點名稱-------------------------");
- Iterator<String> fieldNames = node.fieldNames();
- while (fieldNames.hasNext()) {
- String fieldName = fieldNames.next();
- System.out.print(fieldName+" ");
- }
- System.out.println("\n-----------------------------------------------------");
-
- 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) {
-
- if(flag){
- System.out.println("provinceElements JsonNodeType:"+provinceElements.getNodeType());
- System.out.println("provinceElements is container node? "+provinceElements.isContainerNode());
- flag = false;
- }
- Iterator<String> 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);
- }
- }
- }
- }
程序運行後打印結果以下:
- 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
- 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"));
-
- 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<String> 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);
- }
- }
- }
-
- }
程序運行打印結果:
- JsonNodeType : MISSING
- country_id:China
- name:Shanxi
- population:37751200
- name:ZheJiang
- population:55080000
3.Stream處理Json
(1)stream生成json
- 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();
-
- 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文件內容:
- {"country_id":"China","provinces":[{"name":"Shanxi","population":33750000}]}
(2)stream解析json:
如今adgcountry3.json,咱們用Streaming API的方式來解析上面的Json,並查找json中population的值。
- 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;
-
- public class StreamParserJson {
- public static void main(String[] args) throws JsonParseException,
- IOException {
- JsonFactory factory = new JsonFactory();
-
- JsonParser parser = factory.createParser(new File("country3.json"));
-
- while (!parser.isClosed()) {
-
- JsonToken token = parser.nextToken();
- if (token == null) {
- break;
- }
-
-
- if (JsonToken.FIELD_NAME.equals(token)
- && "provinces".equals(parser.getCurrentName())) {
- token = parser.nextToken();
- if (!JsonToken.START_ARRAY.equals(token)) {
- break;
- }
-
- 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)
- && "population".equals(parser.getCurrentName())) {
- token = parser.nextToken();
- System.out.println(parser.getCurrentName() + " : "
- + parser.getIntValue());
- }
- }
- }
- }
- }
-
- }
程序運行後,在控制檯打印結果以下:
總結
上面的例子中,分別用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方法輕鬆查找內容。