jackson快速入门

1. 背景
目前维护的产品使用jackson处理json,现整理一下jackson相关资料,希望对初次接触jackson的新手有所帮助。
    jackson主页: http://jackson.codehaus.org/
    jackson document: http://wiki.fasterxml.com/JacksonJavaDocs
    JacksonInFiveMinutes: http://wiki.fasterxml.com/JacksonInFiveMinutes
    本文主要内容译自JacksonInFiveMinutes,增加了部分示例,转载请注明出处。
受java平台上各种处理xml的类库(StAX, JAXB等)启发,Jackson提供一种处理json的java类库。Jackson的目标是为开发者提供快速、准确、轻量级和用起来最爽的json处理类库。本文将概括介绍Jackson的主要功能和相关功能的使用示例。

 

2.  使用方式
Jackson提供三种可选的json处理方式:
1) Streaming API
又称Incremental parsing/generation, 受StAX API启发,以非关联递增方式读写json内容。 通过org.codehaus.jackson.JsonParser读取,通过org.codehaus.jackson.JsonGenerator写入。

2) Tree Model

通过基于内存的树形结构来描述json数据,和 XML DOM类似。通过org.codehaus.jackson.map.ObjectMapper构建树,树由JsonNode节点组成 

3) Data Binding 

基于属性访问或注解的方式将json和POJO对象互相转换, 受JAXB基于注解的处理方式启发。通过org.codehaus.jackson.map.ObjectMapper读写json数据。它包含两种类型:

3.1 Simple Data Binding

用于json和Java Maps, Lists, Strings, Numbers, Booleans and nulls的相互转换。

3.2 Full Data Binding

用于json和Java Bean的相互转换。

 

下面从使用的角度上比较三种处理方式:

Streaming API 执行效率最高,读写速度最快,另外两种方式都基于它实现;

Tree Model 是最灵活的;

Data Binding 通常是最方便使用的;


3.  示例

快速上手最好的方式就是看示例,下面的例子演示了上面三种方式的用法,建议通过附件下载完整的示例工程文件。

 

  1 package com.learnworld.jackson.main;
  2 
  3 import java.io.File;
  4 import java.util.Date;
  5 import java.util.HashMap;
  6 import java.util.Map;
  7 
  8 import org.codehaus.jackson.JsonEncoding;
  9 import org.codehaus.jackson.JsonFactory;
 10 import org.codehaus.jackson.JsonGenerator;
 11 import org.codehaus.jackson.JsonNode;
 12 import org.codehaus.jackson.JsonParser;
 13 import org.codehaus.jackson.JsonToken;
 14 import org.codehaus.jackson.map.ObjectMapper;
 15 import org.codehaus.jackson.node.ObjectNode;
 16 import org.codehaus.jackson.type.TypeReference;
 17 
 18 import com.learnworld.jackson.annotation.Account;
 19 import com.learnworld.jackson.pojo.Name;
 20 import com.learnworld.jackson.pojo.User;
 21 import com.learnworld.jackson.pojo.User.Gender;
 22 
 23 public class JacksonMain {
 24 
 25     /**
 26      * @param args
 27      * @throws Exception
 28      */
 29     public static void main(String[] args) throws Exception {
 30         ObjectMapper mapper = new ObjectMapper();
 31         
 32         // 1.1 Simple Data Binding
 33         simpleDataBinding(mapper);
 34         
 35         // 1.2 Full Data Binding
 36         fullDataBinding(mapper);
 37         
 38         // 1.3 Data Binding with Generics
 39         dataBindingWithGenerics(mapper);
 40         
 41         // 1.4 Data Binding with Annotation
 42         dataBindingWithAnnotation(mapper);
 43         
 44         // 2.1 Tree Model
 45         treeModel(mapper);
 46         
 47         // 2.2 Construct a Tree
 48         constructTreeModel(mapper);
 49         
 50         // 3.1 Streaming API (write Json)
 51         streamingAPIWrite();
 52         
 53         // 3.2 Streaming API (read Json)
 54         streamingAPIRead();
 55     }
 56 
 57     @SuppressWarnings("unchecked")
 58     public static void simpleDataBinding(ObjectMapper mapper) throws Exception {
 59         // json -> Map
 60         Map<String, Object> userDataRead = mapper.readValue(new File("user.json"),
 61                 Map.class);
 62         System.out.println("simpleDataBinding(): " + userDataRead);
 63     
 64         // Map -> json
 65         Map<String,Object> userData = new HashMap<String,Object>();
 66         Map<String,String> nameStruct = new HashMap<String,String>();
 67         nameStruct.put("first", "Joe");
 68         nameStruct.put("last", "Sixpack");
 69         userData.put("name", nameStruct);
 70         userData.put("gender", "MALE");
 71         userData.put("verified", Boolean.FALSE);
 72         userData.put("userImage", "Rm9vYmFyIQ==");
 73         mapper.writeValue(new File("user-modified.json"), userData);
 74     }
 75 
 76     public static void fullDataBinding(ObjectMapper mapper) throws Exception {
 77         // json -> Object
 78         User user = mapper.readValue(new File("user.json"), User.class);
 79         System.out.println("fullDataBinding(): " + user);
 80 
 81         // Object -> json
 82         mapper.writeValue(new File("user-modified.json"), user);
 83     }
 84     
 85     public static void dataBindingWithGenerics(ObjectMapper mapper) throws Exception {
 86         // json -> Map
 87         Map<String, Name> genericData = mapper.readValue(new File("generic.json"),
 88                 new TypeReference<Map<String,Name>>() { });
 89         System.out.println("dataBindingWithGenerics():" + genericData);
 90     }
 91     
 92     public static void dataBindingWithAnnotation(ObjectMapper mapper) throws Exception {
 93         // json -> Object
 94         Account account = mapper.readValue(new File("account.json"), Account.class);
 95         System.out.println("dataBindingWithAnnotation(): " + account);
 96 
 97         account.setGmtCreate(new Date());
 98         // Object -> json
 99         mapper.writeValue(new File("account.json"), account);
100     }
101     
102     public static void treeModel(ObjectMapper mapper) throws Exception {
103         // can either use mapper.readTree(JsonParser), or bind to JsonNode
104         JsonNode rootNode = mapper.readValue(new File("user.json"), JsonNode.class);
105         
106         // ensure that "last name" isn't "Xmler"; if is, change to "Jsoner"
107         JsonNode nameNode = rootNode.path("name");
108         String lastName = nameNode.path("last").getTextValue();
109         if ("xmler".equalsIgnoreCase(lastName)) {
110           ((ObjectNode)nameNode).put("last", "Jsoner");
111         }
112         // write it out
113         mapper.writeValue(new File("user-modified.json"), rootNode);
114     }
115     
116     public static void constructTreeModel(ObjectMapper mapper) throws Exception {
117         ObjectMapper objectMapper = new ObjectMapper();
118         ObjectNode userOb = objectMapper.createObjectNode();
119         ObjectNode nameOb = userOb.putObject("name");
120         nameOb.put("first", "Thomas");
121         nameOb.put("last", "Zhou");
122         userOb.put("gender", User.Gender.MALE.toString());
123         userOb.put("verified", false);
124         userOb.put("userImage", "Foobar!".getBytes());
125         // write it out
126         mapper.writeValue(new File("user-modified.json"), userOb);
127     }
128     
129     public static void streamingAPIRead() throws Exception {
130         JsonFactory f = new JsonFactory();
131         JsonGenerator g = f.createJsonGenerator(new File("user.json"), JsonEncoding.UTF8);
132 
133         g.writeStartObject();
134         g.writeObjectFieldStart("name");
135         g.writeStringField("first", "Thomas");
136         g.writeStringField("last", "Zhou");
137         g.writeEndObject(); // for field 'name'
138         g.writeStringField("gender", Gender.MALE.name());
139         g.writeBooleanField("verified", false);
140         g.writeFieldName("userImage"); // no 'writeBinaryField' (yet?)
141         byte[] binaryData = "Foobar!".getBytes();
142         g.writeBinary(binaryData);
143         g.writeEndObject();
144         g.close(); // important: will force flushing of output, close underlying output stream
145     }
146     
147     public static void streamingAPIWrite() throws Exception {
148         JsonFactory f = new JsonFactory();
149         JsonParser jp = f.createJsonParser(new File("user.json"));
150         User user = new User();
151         jp.nextToken(); // will return JsonToken.START_OBJECT (verify?)
152         while (jp.nextToken() != JsonToken.END_OBJECT) {
153           String fieldname = jp.getCurrentName();
154           jp.nextToken(); // move to value, or START_OBJECT/START_ARRAY
155           if ("name".equals(fieldname)) { // contains an object
156             Name name = new Name();
157             while (jp.nextToken() != JsonToken.END_OBJECT) {
158               String namefield = jp.getCurrentName();
159               jp.nextToken(); // move to value
160               if ("first".equals(namefield)) {
161                 name.setFirst(jp.getText());
162               } else if ("last".equals(namefield)) {
163                 name.setLast(jp.getText());
164               } else {
165                 throw new IllegalStateException("Unrecognized field '"+fieldname+"'!");
166               }
167             }
168             user.setName(name);
169           } else if ("gender".equals(fieldname)) {
170             user.setGender(User.Gender.valueOf(jp.getText()));
171           } else if ("verified".equals(fieldname)) {
172             user.setVerified(jp.getCurrentToken() == JsonToken.VALUE_TRUE);
173           } else if ("userImage".equals(fieldname)) {
174             user.setUserImage(jp.getBinaryValue());
175           } else {
176             throw new IllegalStateException("Unrecognized field '"+fieldname+"'!");
177           }
178         }
179         jp.close(); // ensure resources get cleaned up timely and properly
180         System.out.println("streamingAPIWrite(): " + user);
181     }
182 }

4.  其他

除了使用上文中演示的ObjectMapper方式使用data binding和tree model以下方法也可以满足你的需求:

  • JsonParser.readValueAs()

  • JsonParser.readValueAsTree()

  • JsonGenerator.writeObject()

  • JsonGenerator.writeTree()

转载:http://learnworld.iteye.com/blog/1616866

posted on 2014-05-27 10:22  沧海一述苦笑天  阅读(614)  评论(0编辑  收藏  举报

导航