1、官方参考 
2、简介 Jackson 有两个主要分支,1.x 处于维护状态,只会发布 bug 修复版本。2.x 还在积极地开发当中。这两个版本的 Java 包名和 Maven artifact 不一样,所以它们不互相兼容,但是可以和平共存,项目可以同时依赖 1.x 和 2.x 而不会发生冲突。
Jackson 1.x(目前版本从 1.1~1.9)与 2.x 版本的依赖从包名可以看出来。1.x 的类库中,包命名以:org.codehaus.jackson.xxx 开头,而 2.x 类库中包命令:com.fastxml.jackson.xxx 开头。
3、主要模块 1)核心模块
核心模块是扩展模块构建的基础,到 2.7 版本为止,共有 3 个核心模块(依赖关系从上到下):
Streaming  : jackson-core jar,定义了底层的 streaming API 和实现了 Json 特性。Annotations  : jackson-annotations jar,包含了标准的 Jackson 注解。Databind  : jackson-databind jar,实现了数据绑定和对象序列化,它依赖于 streaming 和 annotations 的包。 
2)第三方数据类型模块
这些扩展是插件式的 Jackson 模块,用 ObjectMapper.registerModule() 注册,并且通过添加 serializers 和 deserializers 以便 Databind 包(ObjectMapper / ObjectReader / ObjectWriter)可以读写这些类型,来增加对各种常用的 Java 库的数据类型的支持。参考:https://github.com/FasterXML/jacksonThird-party  datatype modules。
3)数据格式模块
Jackson 也有处理程序对 JAX-RS 标准实现者例如 Jersey, RESTeasy, CXF 等提供了数据格式支持。处理程序实现了 MessageBodyReader 和 MessageBodyWriter,目前支持的数据格式包括 JSON, Smile, XML, YAML 和 CBOR。
数据格式提供了除了 Json 之外的数据格式支持,它们绝大部分仅仅实现了 streaming API abstractions,以便数据绑定组件可以按照原来的方式使用。另一些(几乎不需要)提供了 databind 标准功能来处理例如 schemas。参考https://github.com/FasterXML/jacksonData  format modules
4)jackon 的三个核心类库
maven 依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <dependency >   <groupId > com.fasterxml.jackson.core</groupId >    <artifactId > jackson-core</artifactId >    <version > 2.7.4</version >  </dependency > <dependency >   <groupId > com.fasterxml.jackson.core</groupId >    <artifactId > jackson-annotations</artifactId >    <version > 2.7.4</version >  </dependency > <dependency >   <groupId > com.fasterxml.jackson.core</groupId >    <artifactId > jackson-databind</artifactId >    <version > 2.7.4</version >  </dependency > 
4、处理 Json Jackson 提供了三种可选的 Json 处理方法:流式 API(Streaming API)、树模型(Tree Model)、数据绑定(Data Binding)。三种处理 Json 的方式的特性:
Streaming API:是效率最高的处理方式(开销低、读写速度快,但程序编写复杂度高) 
Tree Model:是最灵活的处理方式 
Data Binding:是最常用的处理方式 
 
1)Data Binding
主要使用 ObjectMapper 来操作 Json,默认情况下会使用 BeanSerializer 来序列化 POJO。 
如果是解析,那么如下的例子里的 TestJson 必须要有 setters,且 setters 必须是 public 修饰的,否则属性的值将会为 null。 
如果是生成,那么必须有 getters,且 getters 必须是 public 修饰的。 
如果属性不是 private 修饰,那么可以不用有 getters 和 setters。 
 
要点:
1 2 3 ObjectMapper  mapper  =  new  ObjectMapper ();mapper.writeValue(jsonFile, Bean); mapper.readValue(jsonFile, Bean.class 或 Collection<Bean>); 
1)生成 json
city.java 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package  com.myjackson.databinding;public  class  City  {    private  Integer id;     private  String cityName;     public  City () {}     public  Integer getId ()  {         return  id;     }     public  void  setId (Integer id)  {         this .id = id;     }     public  String getCityName ()  {         return  cityName;     }     public  void  setCityName (String cityName)  {         this .cityName = cityName;     } } 
province.java 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package  com.myjackson.databinding;import  java.util.Date;import  java.util.List;public  class  Province  {    private  Integer id;     private  String name;     private  Date birthDate;     private  List<City> cities;     public  Province () {}     public  Integer getId ()  {         return  id;     }     public  void  setId (Integer id)  {         this .id = id;     }     public  String getName ()  {         return  name;     }     public  void  setName (String name)  {         this .name = name;     }     public  List<City> getCities ()  {         return  cities;     }     public  void  setCities (List<City> cities)  {         this .cities = cities;     }     public  Date getBirthDate ()  {         return  birthDate;     }     public  void  setBirthDate (Date birthDate)  {         this .birthDate = birthDate;     } } 
country.java 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 package  com.myjackson.databinding;import  java.util.Date;import  java.util.HashMap;import  java.util.List;import  java.util.Map;public  class  Country  {    private  Integer id;     private  String countryName;     private  Date establishTime;     private  List<Province> provinces;     private  String[] lakes;     private  Map<String, String> forest = new  HashMap <String, String>();     public  Country () {     }     public  Integer getId ()  {         return  id;     }     public  void  setId (Integer id)  {         this .id = id;     }     public  String getCountryName ()  {         return  countryName;     }     public  void  setCountryName (String countryName)  {         this .countryName = countryName;     }     public  Date getEstablishTime ()  {         return  establishTime;     }     public  void  setEstablishTime (Date establishTime)  {         this .establishTime = establishTime;     }     public  List<Province> getProvinces ()  {         return  provinces;     }     public  void  setProvinces (List<Province> provinces)  {         this .provinces = provinces;     }     public  String[] getLakes() {         return  lakes;     }     public  void  setLakes (String[] lakes)  {         this .lakes = lakes;     }     public  Map<String, String> getForest ()  {         return  forest;     }     public  void  setForest (Map<String, String> forest)  {         this .forest = forest;     } } 
测试案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 @Test public  void  Bean2JsonStr ()  throws  ParseException, JsonGenerationException, JsonMappingException, IOException{         ObjectMapper  mapper  =  new  ObjectMapper ();     SimpleDateFormat  dateFormat  =  new  SimpleDateFormat ("yyyy-MM-dd" );     mapper.setDateFormat(dateFormat);      City  city1  =  new  City ();     city1.setId(1 );     city1.setCityName("gz" );     City  city2  =  new  City ();     city2.setId(2 );     city2.setCityName("dg" );     Province  province  =  new  Province ();     province.setId(1 );     province.setName("GD" );     province.setBirthDate(new  Date ());     List<City> cities = new  ArrayList <City>();     cities.add(city1);     cities.add(city2);     province.setCities(cities);     Country  country  =  new  Country ();     country.setCountryName("China" );     country.setId(1 );     country.setEstablishTime(dateFormat.parse("1949-10-01" ));     country.setLakes(new  String [] { "Qinghai Lake" , "Poyang Lake" ,"Dongting Lake" , "Taihu Lake"  });     HashMap<String, String> forest = new  HashMap <String, String>();     forest.put("no.1" , "dxal" );     forest.put("no.2" , "xxal" );     country.setForest(forest);     List<Province> provinces = new  ArrayList <Province>();     provinces.add(province);     country.setProvinces(provinces);     mapper.configure(SerializationFeature.INDENT_OUTPUT, true );          mapper.setSerializationInclusion(Include.NON_EMPTY);       mapper.writeValue(new  File ("country.json" ), country);   } 
运行得到 country.json:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 {   "id" :  1 ,    "countryName" :  "China" ,    "establishTime" :  "1949-10-01" ,    "provinces" :  [      {        "id" :  1 ,        "name" :  "GD" ,        "birthDate" :  "2017-02-04" ,        "cities" :  [          {            "id" :  1 ,            "cityName" :  "gz"          } ,          {            "id" :  2 ,            "cityName" :  "dg"          }        ]      }    ] ,    "lakes" :  [ "Qinghai Lake" ,  "Poyang Lake" ,  "Dongting Lake" ,  "Taihu Lake" ] ,    "forest" :  {      "no.1" :  "dxal" ,      "no.2" :  "xxal"    }  } 
2)解析 json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Test public  void  JsonStr2Bean ()  throws  JsonParseException, JsonMappingException, IOException{    ObjectMapper  mapper  =  new  ObjectMapper ();     File  jsonFile  =  new  File ("country.json" );               mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);     Country  country  =  mapper.readValue(jsonFile, Country.class);     System.out.println(country.getCountryName()+country.getEstablishTime());     List<Province> provinces = country.getProvinces();     for  (Province province : provinces) {         System.out.println("province:" +province.getName() + "\n"  + "birthDate:" +province.getBirthDate());         for  (City city: province.getCities()) {             System.out.println(city.getId()+" " +city.getCityName());         }     } } 
输出结果:
1 2 3 4 5 ChinaSat Oct 01 08:00:00 CST 1949 province:GD getBirthDate:Sat Feb 04 08:00:00 CST 2017 1 gz 2 dg 
解析的时候如果碰到集合类,那么可以使用 TypeReference 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Test public  void  JsonStr2List ()  throws  IOException{    City  city1  =  new  City ();     city1.setId(1 );     city1.setCityName("gz" );     City  city2  =  new  City ();     city2.setId(2 );     city2.setCityName("dg" );     List<City> cities = new  ArrayList <City>();     cities.add(city1);     cities.add(city2);     ObjectMapper  mapper  =  new  ObjectMapper ();     String  listJsonStr  =  mapper.writeValueAsString(cities);     System.out.println(listJsonStr);     List<City> list = mapper.readValue(listJsonStr, new   TypeReference <List<City>>(){} );     for  (City city: list) {         System.out.println("id:" +city.getId()+" cityName:" +city.getCityName());     } } 
2)Streaming API
Jackson 提供了一套底层 API 来解析 Json 字符串,这个 API 为每个 Json 对象提供了符号。例如, ‘{’ 是解析器提供的第一个对象(writeStartObject()),键值对是解析器提供的另一个单独对象(writeString(key,value))。这些 API 很强大,但是需要大量的代码。大多数情况下,Tree Model 和 Data Binding 可以代替 Streaming API。
上面代码如果注释掉 city1.setId(1);这行,结果为:
1 2 3 [{"id" :null,"cityName" :"gz" },{"id" :2,"cityName" :"dg" }] id :null cityName:gzid :2 cityName:dg
但假如想让 id 为 null 的不输出,不为 null 的输出除了 mapper.setSerializationInclusion(Include.NON_EMPTY); // 配置 mapper 忽略空属性 这种方法外还可以在 ObjectMapper 中注册一个自定义的序列化 JsonSerializer 和反序列化
CityJsonSerializer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package  com.myjackson.databinding;import  java.io.IOException;import  com.fasterxml.jackson.core.JsonGenerator;import  com.fasterxml.jackson.core.JsonProcessingException;import  com.fasterxml.jackson.databind.JsonSerializer;import  com.fasterxml.jackson.databind.SerializerProvider;public  class  CityJsonSerializer  extends  JsonSerializer <City>{    @Override      public  void  serialize (City city, JsonGenerator jsonGenerator, SerializerProvider arg2)              throws  IOException, JsonProcessingException {          jsonGenerator.writeStartObject();          if  ( city.getId()!=null ) {              jsonGenerator.writeNumberField("id" , city.getId());          }          jsonGenerator.writeStringField("cityName" , city.getCityName());          jsonGenerator.writeEndObject();     } } 
CityJsonDeSerializer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package  com.myjackson.databinding;import  java.io.IOException;import  java.util.ArrayList;import  java.util.List;import  com.fasterxml.jackson.core.JsonParser;import  com.fasterxml.jackson.core.JsonProcessingException;import  com.fasterxml.jackson.core.JsonToken;import  com.fasterxml.jackson.databind.DeserializationContext;import  com.fasterxml.jackson.databind.JsonDeserializer;public  class  CityJsonDeSerializer  extends  JsonDeserializer <List<City>>{    @Override      public  List<City> deserialize (JsonParser parser,DeserializationContext deserializationcontext)  throws  IOException,             JsonProcessingException {         List<City> list = new  ArrayList <City>();                   if  (!JsonToken.START_ARRAY.equals(parser.getCurrentToken())) {              System.out.println(parser.getCurrentToken());              return  null ;          }                  while  (!parser.isClosed()) {                          JsonToken  token  =  parser.nextToken();                          if  (token == null )                 break ;                          if  (!JsonToken.START_OBJECT.equals(token)) {                 break ;             }             City  city  =  null ;                          while  (true ) {                 if  (JsonToken.START_OBJECT.equals(token)) {                     city = new  City ();                 }                 token = parser.nextToken();                 if  (token == null )                     break ;                 if  (JsonToken.FIELD_NAME.equals(token) ) {                     if ("id" .equals(parser.getCurrentName())){                         token = parser.nextToken();                         city.setId(parser.getIntValue());                     }else  if ("cityName" .equals(parser.getCurrentName())){                         token = parser.nextToken();                         city.setCityName(parser.getText());                     }                 }                 if (JsonToken.END_OBJECT.equals(token)){                     list.add(city);                 }             }         }         return  list;     } } 
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Test public  void  StreamJsonStr2List ()  throws  IOException{    City  city1  =  new  City ();          city1.setCityName("gz" );     City  city2  =  new  City ();     city2.setId(2 );     city2.setCityName("dg" );     List<City> cities = new  ArrayList <City>();     cities.add(city1);     cities.add(city2);     ObjectMapper  mapper  =  new  ObjectMapper ();     SimpleModule  module  =  new  SimpleModule ();     module .addSerializer(City.class, new  CityJsonSerializer ());     mapper.registerModule(module );     String  listJsonStr  =  mapper.writeValueAsString(cities);     System.out.println(listJsonStr);     ObjectMapper  mapper2  =  new  ObjectMapper ();     SimpleModule  module2  =  new  SimpleModule ();     module2.addDeserializer(List.class, new  CityJsonDeSerializer ());     mapper2.registerModule(module2);     List<City> list = mapper2.readValue(listJsonStr, new   TypeReference <List<City>>(){} );     for  (City city: list) {         System.out.println("id:" +city.getId()+" cityName:" +city.getCityName());     } } 
也可以简单一点,使用注解,省去在 ObjectMapper 中注册 SimpleModule
1 2 3 4 5 6 import  com.fasterxml.jackson.databind.annotation.JsonSerialize;@JsonSerialize(using=CityJsonSerializer.class) public  class  City  {... } 
运行结果:
1 2 3 [{"cityName" :"gz" },{"id" :2,"cityName" :"dg" }] id :null cityName:gzid :2 cityName:dg
3)Tree Mode
如果不想为 Json 结构写一个 class 的话,Tree Mode 是一个很好的选择。
生成 json:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @Test public  void  TreeMode2Json ()  throws  IOException{                 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("id" ,   1 );         country.put("countryName" ,"China" );         country.put("establishTime" , "1949-10-01" );         ArrayNode  provinces  =  factory.arrayNode();         ObjectNode  province  =  factory.objectNode();         ObjectNode  city1  =  factory.objectNode();         city1.put("id" , 1 );         city1.put("cityName" , "gz" );         ObjectNode  city2  =  factory.objectNode();         city2.put("id" , 1 );         city2.put("cityName" , "dg" );         ArrayNode  cities  =  factory.arrayNode();         cities.add(city1).add(city2);         province.put("cities" , cities);         provinces.add(province);         country.put("provinces" ,provinces);         ArrayNode  lakes  =  factory.arrayNode();         lakes.add("QingHai Lake" ).add("Poyang Lake" ).add("Dongting Lake" ).add("Taihu Lake" );         country.put("lakes" ,lakes);         ObjectNode  forest  =  factory.objectNode();         forest.put("no.1" ,"dxal" );         forest.put("no.2" , "xxal" );         country.put("forest" , forest);         mapper.setSerializationInclusion(Include.NON_EMPTY);           mapper.writeTree(generator, country);     } 
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 {   "id" :  1 ,    "countryName" :  "China" ,    "establishTime" :  "1949-10-01" ,    "provinces" :  [      {        "cities" :  [          {  "id" :  1 ,  "cityName" :  "gz"  } ,          {  "id" :  1 ,  "cityName" :  "dg"  }        ]      }    ] ,    "lakes" :  [ "QingHai Lake" ,  "Poyang Lake" ,  "Dongting Lake" ,  "Taihu Lake" ] ,    "forest" :  {  "no.1" :  "dxal" ,  "no.2" :  "xxal"  }  } 
读取 json:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Test public  void  TreeModeReadJson ()  throws  IOException{    ObjectMapper  mapper  =  new  ObjectMapper ();          JsonNode  node  =  mapper.readTree(new  File ("country2.json" ));          System.out.println("node JsonNodeType:" +node.getNodeType());     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  lakes  =  node.get("lakes" );     System.out.println("lakes:" +lakes+" JsonNodeType:" +lakes.getNodeType()); } 
运行结果:
1 2 3 4 5 6 7 node JsonNodeType:OBJECT ---------得到所有 node 节点的子节点名称------------------------- id countryName establishTime provinces lakes forest --- lakes:["QingHai Lake" ,"Poyang Lake" ,"Dongting Lake" ,"Taihu Lake" ] JsonNodeType:ARRAY 
5、结束 Stream API 方式是开销最低、效率最高,但编写代码复杂度也最高,在生成 Json 时,需要逐步编写符号和字段拼接 json,在解析 Json 时,需要根据 token 指向也查找 json 值,生成和解析 json 都不是很方便,代码可读性也很低。
TreeModel 处理 Json,是以树型结构来生成和解析 json,生成 json 时,根据 json 内容结构,我们创建不同类型的节点对象,组装这些节点生成 json。解析 json 时,它不需要绑定 json 到 java bean,根据 json 结构,使用 path 或 get 方法轻松查找内容。
6、解析 Json 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 import  java.io.IOException;import  java.text.SimpleDateFormat;import  java.util.Date;import  java.util.TimeZone;import  com.fasterxml.jackson.core.JsonProcessingException;import  com.fasterxml.jackson.databind.JsonNode;import  com.fasterxml.jackson.databind.ObjectMapper;public  class  ParseJsonTest  {         public  static  void  main (String[] args)  {         String  data  =  "{\"type\":2,\"range\":1,\"start\":1368417600,\"end\":1368547140,"                  + "\"cityName\":\"天津\",\"companyIds\":[\"12000001\"],\"companyNames\":[\"天津\"],"                  + "\"12000001\":{\"data\":[47947,48328,48573,48520],"                  + "\"timestamps\":[1368417600,1368417900,1368418200,1368418500]}}" ;         String  data2  =  parseJson(data);         System.out.println(data2);     }     public  static  String parseJson (String data)  {                  StringBuffer  buf  =  new  StringBuffer ();         ObjectMapper  mapper  =  new  ObjectMapper ();         JsonNode  rootNode  =  mapper.readTree(data);                   int  type  =  rootNode.path("type" ).asInt();         int  range  =  rootNode.path("range" ).asInt();         long  start  =  rootNode.path("start" ).asLong();         long  end  =  rootNode.path("end" ).asLong();         String  cityName  =  rootNode.path("cityName" ).asText();                  SimpleDateFormat  sdf  =  new  SimpleDateFormat ("yyyyMMddHHmm" );         sdf.setTimeZone(TimeZone.getTimeZone("GMT+8" ));         String  str  =  "类型(type):"  + type + "\r\n"  + "范围(range):"  + range                 + "\r\n"  + "开始时间(start):"                  + sdf.format(new  Date (start * 1000 )) + "\r\n"                  + "结束时间(end):"  + sdf.format(new  Date (end * 1000 )) + "\r\n"                  + "城市名称(cityName):"  + cityName;         buf.append(str);                  JsonNode  companyIds  =  rootNode.path("companyIds" );         JsonNode  companyNames  =  rootNode.path("companyNames" );                  for  (int  i  =  0 ; i < companyIds.size(); i++) {             String  companyId  =  companyIds.get(i).asText();                          String  companyName  =  companyNames.get(i).asText();                                       JsonNode  infoNode  =  rootNode.path(companyId);                          JsonNode  dataNode  =  infoNode.path("data" );             JsonNode  timestampsNode  =  infoNode.path("timestamps" );                          buf.append("\r\n{\r\n  公司ID(companyId):"  + companyId                     + "\r\n  公司名称(companyName):"  + companyName + "\r\n"                      + " data:" );             for  (int  j  =  0 ; j < dataNode.size(); j++) {                 long  dataValue  =  dataNode.get(j).asLong();                 buf.append(dataValue + "," );             }             buf.append("\r\n time:" );             for  (int  k  =  0 ; k < timestampsNode.size(); k++) {                 long  timeValue  =  timestampsNode.get(k).asLong();                 buf.append(sdf.format(new  Date (timeValue * 1000 )) + "," );             }             buf.append("\r\n}\r\n" );         }         return  buf.toString();     } } 
测试结果:
1 2 3 4 5 6 7 8 9 10 11 类型(type ):2 范围(range):1 开始时间(start):201305131200 结束时间(end):201305142359 城市名称(cityName):天津 {   公司ID(companyId):12000001   公司名称(companyName):天津   data:47947,48328,48573,48520,   time:201305131200,201305131205,201305131210,201305131215 }