Jackson JSON说明

来源:互联网 发布:算法 mobi 编辑:程序博客网 时间:2024/06/07 16:30

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.

 

目录

  1. JSON Three Ways
  2. Examples
    1. Full Data Binding (POJO) Example
    2. Simple Data Binding Example
    3. Data Binding with Generics
    4. Tree Model Example
    5. Streaming API Example

 

 

JSON Three Ways

 

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.

    • The tree model is similar to the XML DOM.
  • 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.

 

Examples

 

 

Full Data Binding (POJO) Example

 

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).