Inspired by the quality and variety of XML tooling available for the Java platform (StAX, JAXB, etc.), the Jackson is a multi-purpose Java library for processing JSON. Jackson aims to be the best possible combination of fast, correct, lightweight, and ergonomic for developers.
This page gives an overview of Jackson's capabilities.
目录
Jackson offers three alternative methods (one with two variants) for processing JSON:
Streaming API (aka "Incremental parsing/generation") reads and writes JSON content as discrete events.
org.codehaus.jackson.JsonParser reads, org.codehaus.jackson.JsonGenerator writes.
Inspired by the StAX API.
Tree Model provides a mutable in-memory tree representation of a JSON document.
org.codehaus.jackson.map.TreeMapper builds trees; trees consist of org.codehaus.jackson.map.JsonNode nodes.
Data Binding converts JSON to and from POJOs based either on property accessor conventions or annotations.
There are two variants: simple and full data binding
Simple data binding means converting to and from Java Maps, Lists, Strings, Numbers, Booleans and nulls
Full data binding means converting to and from any Java bean type (as well as "simple" types mentioned above)
org.codehaus.jackson.map.ObjectMapper performs the marshalling and unmarshalling for both variants.
Inspired by the annotation-based (code-first) variant of JAXB.
From usage perspective, one way to summarize these 3 methods is:
Streaming API is best performing (lowest overhead, fastest read/write; other 2 methods build on it)
Data Binding is often most convenient
Tree Model is most flexible
Given these properties, let's consider these in the reverse order, starting with what is usually the most natural and convenient method for Java developers: Jackson Data Binding API.
Jackson's org.codehaus.jackson.map.ObjectMapper "just works" for mapping JSON data into plain old Java objects ("POJOs"). For example, given JSON data
{ "name" : { "first" : "Joe", "last" : "Sixpack" }, "gender" : "MALE", "verified" : false, "userImage" : "Rm9vYmFyIQ==" }
It takes two lines of Java to turn it into a User instance:
1 JsonFactory f = new JsonFactory(); 2 JsonParser jp = f.createJsonParser(new File("user.json")); 3 User user = new User(); 4 jp.nextToken(); // will return JsonToken.START_OBJECT (verify?) 5 while (jp.nextToken() != JsonToken.END_OBJECT) { 6 String fieldname = jp.getCurrentName(); 7 jp.nextToken(); // move to value, or START_OBJECT/START_ARRAY 8 if ("name".equals(fieldname)) { // contains an object 9 Name name = new Name(); 10 while (jp.nextToken() != JsonToken.END_OBJECT) { 11 String namefield = jp.getCurrentName(); 12 jp.nextToken(); // move to value 13 if ("first".equals(namefield)) { 14 name.setFirst(jp.getText()); 15 } else if ("last".equals(namefield)) { 16 name.setLast(jp.getText()); 17 } else { 18 throw new IllegalStateException("Unrecognized field '"+fieldname+"'!"); 19 } 20 } 21 user.setName(name); 22 } else if ("gender".equals(fieldname)) { 23 user.setGender(Gender.valueOf(jp.getText())); 24 } else if ("verified".equals(fieldname)) { 25 user.setVerified(jp.getCurrentToken() == JsonToken.VALUE_TRUE); 26 } else if ("userImage".equals(fieldname)) { 27 user.setUserImage(jp.getBinaryValue()); 28 } else { 29 throw new IllegalStateException("Unrecognized field '"+fieldname+"'!"); 30 } 31 } 32 jp.close(); // ensure resources get cleaned up timely and properly
which is quite a bit more than you'll use with data binding.
One final trick: it is also possible to use data binding and tree model directly from JsonParser and JsonGenerator. To do this, have a look at methods:
JsonParser.readValueAs()
JsonParser.readValueAsTree()
JsonGenerator.writeObject()
JsonGenerator.writeTree()
which do about what you might expect them to do.
The only (?) trick is that you MUST make sure you use org.codehaus.jackson.map.MappingJsonFactory for constructing "data-binding capable" parser and generator instances (instead of basic org.codehaus.jackson.JsonFactory).