jackJson

在Java平台(StAX, JAXB等)XML处理质量和多样化的激励下,Jackson为多功能的Java JSON处理包其目标为集快捷、正确、轻量和符合人体工程学与一体。

本文将给出Jackson的功能概览。

JSON的三种处理方式 
Jackson提供了三种可选的JSON处理方法(一种方式及其两个变型):

  • 流式 API(也称为"增量分析/生成") 读取和写入 JSON 内容作为离散事件。

  • 树模型 :提供一个 JSON 文档可变内存树的表示形式。

    • org.codehaus.jackson.map.ObjectMapper 生成树 ;树组成 JsonNode 节点集。

    • 树模型类似于 XML DOM。
  • 数据绑定: JSON和POJO相互转换,基于属性访问器规约或注解。

    • 有 两种变体: 简单 和 完整 的数据绑定:

    • 简单数据绑定: 是指从Java Map、List、String、Numbers、Boolean和空值进行转换

    • 完整数据绑定 :是指从任何 Java bean 类型 (及上文所述的"简单"类型) 进行转换

    • org.codehaus.jackson.map.ObjectMapper 对两个变种,进行编组(marshalling )处理 (写入 JSON) 和反编组(unmarshalling ,读 JSON)。

    • JAXB激励下的基于注释的 (代码优先)变种。

从使用的角度来看,总结这些3 种方法的用法如下:

  • 流 API: 性能最佳的方式 (最低开销、 速度最快的读/写; 其它二者基于它实现)。

  • 数据绑定 :使用最方便的方式。

  • 树模型: 最灵活的方式。

Jackson的 org.codehaus.jackson.map.ObjectMapper "只是"将JSON 数据映射为POJO 对象 。例如,给定 JSON 数据:

{
  "name" : { "first" : "Joe", "last" : "Sixpack" },
  "gender" : "MALE",
  "verified" : false,
  "userImage" : "Rm9vYmFyIQ=="
}

1.用两行代码把它变成一个用户实例:

 ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally

User user = mapper.readValue(new File("user.json"), User.class);

编组为JSON同样简单

mapper.writeValue(new File("user-modified.json"), user);

 

2.Map

Map<String,Object> userData = mapper.readValue(new File("user.json"), Map.class);

 

将如何工作呢? 只定义了Map.class,未定义一般的Key/valie类型,但ObjectMapper 却知晓与Map(及List、数组、wrapper类型 )之间如何相互转换,仅是如此即可。如果它可以正确地映射到您所提供的类型,它将被映射。
 
Jackson将使用简单数据绑定的具体Java 类型包括:

 

JSON Type Java Type
object LinkedHashMap<String,Object>
array ArrayList<Object>
string String
number(no fraction) IntegerLong or BigInteger (smallest applicable)
number (fraction) BigDecimal
true|false boolean
null null

泛型的数据绑定

除绑定到POJO和简单类型外,还有一个额外的变型:绑定到泛型(类型)容器。此时,由于所谓的类型擦除(Java采用向后兼容的方式实现泛型),需要进行特殊处理,以防止使用类似 Collection<String>.class(不被编译)。

所以,热想绑定数据岛Map<String,User>,方式如下:

Map<String,User> result = mapper.readValue(src, new TypeReference<Map<String,User>>() { });

其中TypeReference只需传入泛型类型即可(此时需要匿名内部类):重要部分为<Map<String,User>>,定义要绑定的数据类型。

若不如此(仅定义Map.class),其调用等价于绑定到 Map<?,?>(亦即 “untyped” Map),如前所述。

更新:1.3版的Jackson允许利用TypeFactory实现构造类型。

树模式示例

另一种从JSON获取对象方式是构造“树”,类似于XML的DOM树。Jackson构造树的方法利用JsonNode基类,其中包含公开的通常所需的读取访问方法,实际所用的节点类型为其子类;但子类型仅在修改树时需要。

JSON树可通过流式API或ObjectMapper方式读、写。

利用 ObjectMapper,方法如下:

  1 ObjectMapper m = new ObjectMapper();
   2 // can either use mapper.readTree(JsonParser), or bind to JsonNode
   3 JsonNode rootNode = m.readValue(new File("user.json"), JsonNode.class);
   4 // ensure that "last name" isn't "Xmler"; if is, change to "Jsoner"
   5 JsonNode nameNode = rootNode.path("name");
   6 String lastName = nameNode.path("last").getTextValue().
   7 if ("xmler".equalsIgnoreCase(lastName)) {
   8   ((ObjectNode)nameNode).put("last", "Jsoner");
   9 }
  10 // and write it out:
  11 m.writeValue(new File("user-modified.json"), rootNode);

 

一、入门

Jackson中有个ObjectMapper类很是实用,用于Java对象与JSON的互换。

1、Java对象转换为JSON:

User user=new User(); //Java Object

ObjectMapper mapper = new ObjectMapper();

mapper.writeValueAsString(user); //返回字符串

//输出格式化后的字符串(有性能损耗)

mapper.defaultPrettyPrintingWriter().writeValueAsString(user);

mapper.writeValue(new File("c:\\user.json"), user); //指定文件写入

 

//设置序列化配置(全局),设置序列化时不输出空值.

sharedMapper.getSerializationConfig().setSerializationInclusion(Inclusion.NON_NULL);

 

2、JSON反序列化为Java对象:

ObjectMapper mapper = new ObjectMapper();

//解析器支持解析单引号

mapper.configure(Feature.ALLOW_SINGLE_QUOTES,true);

//解析器支持解析结束符

mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS,true);

HashMap jsonMap = mapper.readValue(json,HashMap.class); //转换为HashMap对象

 

二、Jackson支持3种使用方式:

1、Data Binding:最方便使用.

(1)Full Data Binding:

Java代码   收藏代码
  1. private static final String MODEL_BINDING = "{\"name\":\"name1\",\"type\":1}";  
  2.     public void fullDataBinding() throws Exception{  
  3.         ObjectMapper mapper = new ObjectMapper();  
  4.         Model user = mapper.readValue(MODEL_BINDING, Model.class);//readValue到一个实体类中.  
  5.         System.out.println(user.getName());  
  6.         System.out.println(user.getType());  
  7.     }  

Model类:

Java代码   收藏代码
  1. private static class Model{  
  2.         private String name;  
  3.         private int type;  
  4.           
  5.         public String getName() {  
  6.             return name;  
  7.         }  
  8.         public void setName(String name) {  
  9.             this.name = name;  
  10.         }  
  11.         public int getType() {  
  12.             return type;  
  13.         }  
  14.         public void setType(int type) {  
  15.             this.type = type;  
  16.         }  
  17.     }  

(2)Raw Data Binding:

Java代码   收藏代码
  1. /** 
  2.     Concrete Java types that Jackson will use for simple data binding are: 
  3.     JSON Type       Java Type 
  4.     object          LinkedHashMap<String,Object> 
  5.     array           ArrayList<Object> 
  6.     string          String 
  7.     number(no fraction) Integer, Long or BigInteger (smallest applicable) 
  8.     number(fraction)    Double(configurable to use BigDecimal) 
  9.     true|false      Boolean 
  10.     null            null 
  11.     */  
  12.     public void rawDataBinding() throws Exception{  
  13.         ObjectMapper mapper = new ObjectMapper();  
  14.         HashMap map = mapper.readValue(MODEL_BINDING,HashMap.class);//readValue到一个原始数据类型.  
  15.         System.out.println(map.get("name"));  
  16.         System.out.println(map.get("type"));  
  17.     }  

 (3)generic Data Binding:

Java代码   收藏代码
  1. private static final String GENERIC_BINDING = "{\"key1\":{\"name\":\"name2\",\"type\":2},\"key2\":{\"name\":\"name3\",\"type\":3}}";  
  2.     public void genericDataBinding() throws Exception{  
  3.         ObjectMapper mapper = new ObjectMapper();  
  4.         HashMap<String,Model> modelMap = mapper.readValue(GENERIC_BINDING,new TypeReference<HashMap<String,Model>>(){});//readValue到一个范型数据中.  
  5.         Model model = modelMap.get("key2");  
  6.         System.out.println(model.getName());  
  7.         System.out.println(model.getType());  
  8.     }  

2、Tree Model:最灵活。

Java代码   收藏代码
  1. private static final String TREE_MODEL_BINDING = "{\"treekey1\":\"treevalue1\",\"treekey2\":\"treevalue2\",\"children\":[{\"childkey1\":\"childkey1\"}]}";  
  2.     public void treeModelBinding() throws Exception{  
  3.         ObjectMapper mapper = new ObjectMapper();  
  4.         JsonNode rootNode = mapper.readTree(TREE_MODEL_BINDING);  
  5.         //path与get作用相同,但是当找不到该节点的时候,返回missing node而不是Null.  
  6.         String treekey2value = rootNode.path("treekey2").getTextValue();//  
  7.         System.out.println("treekey2value:" + treekey2value);  
  8.         JsonNode childrenNode = rootNode.path("children");  
  9.         String childkey1Value = childrenNode.get(0).path("childkey1").getTextValue();  
  10.         System.out.println("childkey1Value:"+childkey1Value);  
  11.           
  12.         //创建根节点  
  13.         ObjectNode root = mapper.createObjectNode();  
  14.         //创建子节点1  
  15.         ObjectNode node1 = mapper.createObjectNode();  
  16.         node1.put("nodekey1",1);  
  17.         node1.put("nodekey2",2);  
  18.         //绑定子节点1  
  19.         root.put("child",node1);  
  20.         //数组节点  
  21.         ArrayNode arrayNode = mapper.createArrayNode();  
  22.         arrayNode.add(node1);  
  23.         arrayNode.add(1);  
  24.         //绑定数组节点  
  25.         root.put("arraynode", arrayNode);  
  26.         //JSON读到树节点  
  27.         JsonNode valueToTreeNode = mapper.valueToTree(TREE_MODEL_BINDING);  
  28.         //绑定JSON节点  
  29.         root.put("valuetotreenode",valueToTreeNode);  
  30.         //JSON绑定到JSON节点对象  
  31.         JsonNode bindJsonNode = mapper.readValue(GENERIC_BINDING, JsonNode.class);//绑定JSON到JSON节点对象.  
  32.         //绑定JSON节点  
  33.         root.put("bindJsonNode",bindJsonNode);  
  34.         System.out.println(mapper.writeValueAsString(root));  
  35.     }  

3、Streaming API:最佳性能。

见官方文档例子。

 

参考资料:

1、http://wiki.fasterxml.com/JacksonInFiveMinutes Jackson官方教程示例

2、http://wiki.fasterxml.com/JacksonJavaDocs Jackson在线API文档

3、http://hjg1988.iteye.com/blog/561368 JSON工具性能比较:json-lib和jackson进行Java对象到json字符串序列化。

 

 

 

你可能感兴趣的:(json)