Processing model: Data Binding

Of 3 major processing modes that Jackson supports, data binding is often the most convenient one to use, as it allows for seamless conversion between JSON data and Java objects. It is similar to Tree Model in that JSON content is first converted to Java objects; but instead of using node-based model, regular Java objects are used.

Data binding is built using Streaming API as the underlying JSON reading/writing system: as such it has high-performance (compared to most other Java data binding libraries), but has some additional overhead compared to pure streaming/incremental processing. Generally data binding overhead is lower than actual JSON parsing/writing overhead, however.

There are 2 main "flavors" of data binding:

Both are used via all-powerful ObjectMapper object.

Serialization

There is no real difference between flavors when serializing Java objects -- differences only matter when reading JSON and mapping (binding) it to Java objects. So serialization is achieved by:

  ObjectMapper mapper = new ObjectMapper();
  mapper.writeValue(dst, myBean); // where 'dst' can be File, OutputStream or Writer

Full Data Binding

When using full data binding, deserialization type must be fully specified as something other than Object.class. For example:

  MyBean value = mapper.readValue(src, MyBean.class); // 'src' can be File, InputStream, Reader, String

The main complication is handling of Generic types: if they are used, one has to use TypeReference object, to work around Java Type Erasure:

  MyType<String> genValue = mapper.readValue(src, new TypeReference<MyType<String>>() { });

(why? Because that is one of limited number of ways of passing full type information; mechanism called "Supertype Token")

"Simple" Data Binding

As mentioned above, Simple here just means that range of value types is limited to core JDK types. If this is acceptable, deserialization type can be simply defined as Object.class. This can apply at root level (for calls to ObjectMapper, as well as at lower level -- whatever value are declared to be of basic Object type will use Simple data binding. So something like:

  Object root = mapper.readValue(src, Object.class);
  Map<?,?> rootAsMap = mapper.readValue(src, Map.class);

Also please note that to enable generic type information (like "Map<String,Object>"), you have to use TypeReference container as explained above.

Types used for Simple data binding are:

JSON Type

Java Type

object

LinkedHashMap<String,Object>

array

ArrayList<Object>

string

String

number (no fraction)

Integer, Long or BigInteger (smallest applicable)

number (fraction)

Double (configurable to use BigDecimal)

true|false

Boolean

null

null

where JSON type refers to JSON data types, and "Java Type" to JDK type that such constructs will be mapped to, with Simple data binding.

Configuring

Additional Reading


CategoryJackson

JacksonDataBinding (last edited 2009-10-23 05:15:57 by TatuSaloranta)

Copyright ©2009 FasterXML, LLC