General

Processing Models

Which processing models (streaming, tree, objects) does Jackson implement?

Three main methods (one with 2 alternatives) are implemented:

Most other Java JSON packages only implement one or two of modes: for example, Json.org Reference Implementation just offers access via its custom tree model.

Which mappings (Badgerfish, natural, ...) does Jackson implement?

None. Jackson is "100% JSON" and does not try to imitate or emulate XML. Property name mapping is based on standard Java Bean naming convention (although can be overridden using annotations or custom naming strategy).

There are some support compatibility features -- such as ability to optionally use JAXB annotations -- but fundamentally Jackson is a pure JSON/Java data mapper and tries to minimize impedance between JSON and Java data models.

Data Formats

In addition to textual (standard) JSON, there are also Jackson readers/writers that allow processing JSON-like content that uses other data formats:


Dependencies

Platform

Which JDK does Jackson require?

Up to and including 2.1, JDK 1.5 or above -- this because it makes heavy use of enum types, generics and annotations.

Since 2.2 JDK 1.6 or above.

Jackson should also work on "almost JDK 1.x" level platforms such as Google Android and GAE (to the degree missed pieces of functionality can be worked around); problems should be reported to Jackson team if there are problems in compatibility.

External

Does Jackson depend on other libraries outside of JDK?

No: neither Jackson core nor data mapper have runtime dependencies on external libraries.

Other Jackson jars depend on APIs that may or may not be included in JDK (depending on version), such that:

with.

Starting with 1.6, Jackson also embeds ASM bytecode manipulation library as part of "Mr Bean" extension. Code is repackage using jarjar to avoid conflicts with possible other instances of ASM that may exist in Java classpath.

But I saw some warnings about failing to load Joda DateTime classes?

Later versions (1.4 and above) do offer basic support for some well-known libraries and frameworks, so that there are more compile-time dependencies. During runtime, however, loading is done in a way that missing those libraries should fail gracefully; that is, functionality related to these libraries is not available, but everything else works as expected.

However: some runtimes (reportedly at least Android's JVM, Dalvik), complain about failures to locate classes dynamically. These warnings can be annoying but they are not fatal. Additionally these are platform problem -- Java VM design specifically supports the idea of dynamic discovery, so Jackson's use of dynamic class discovery and loading is solid -- which would be good to bring attention to developers of said platforms. Jackson development team will also gladly accept suggestions for improved handling by Jackson.


Data Binding, general

What mechanism does Jackson use for binding?

Jackson 1.0 supports Bean method - based binding, where serialization requires "getter" methods, and deserialization "setters" (with optional "creator" methods). Version 1.1 also supports direct access of member fields (public instance fields, annotated instance fields).

Also: as of version 1.2, Jackson allows use of "Creator" methods (constructors and static factory methods), which means that it is possible to omit setter methods if data is to be passed via constructor.

How does Jackson map JSON properties to Java methods/fields?

The default mechanism is to use implied name as per Bean convention – for getters and setters leave out "get" or "set", lower case first char – but this can be overridden by annotations (@JsonSetter/@JsonGetter for Jackson 1.0, alternatively @JsonProperty for Jackson 1.1).

With version Jackson 1.1, it is also possible to use subset of JAXB annotations to denote getter and setter methods and fields.

How can I configure data binding aspects?

There are multiple ways to do this:

But I can not modify existing classes to add annotations!

No problem: this is exactly why we added Mix-In Annotation support, so that you can associate annotations as if they were included in class definition, but without having to do that (hence "mix-in" in name). This gives you full power of type-safe annotation-based configuration, but with less tight coupling.

Is ObjectMapper thread-safe?

Short answer: yes

Long answer: yes, as long as you always configure instance before use, and do not call configure methods during operation (or synchronize such calls appropriately). Usually it is better to construct separate mapper instance if configurations differ in any case.

Further: it is beneficial to use just one instance (or small number of instances) for data binding; many optimizations for reuse (of symbol tables, some buffers) depend on ObjectMapper instances being reused.

For more information, check out JacksonFAQThreadSafety


Data Binding, writing (serialization)

Serializing values as simple types

Instead of serializing Java Objects as JSON Objects (via Bean introspection), can't I just serialize them as plain JSON Strings?

Yes. Just annotate property (Java field or getter method that implies property) with @JsonValue; for example:

  @JsonValue public String toString() { return _value.tosString(); }

would make method object.toString() be called to get serialized value. This actually works with any serializable Java types; proper serializer is located based on return type, so there is nothing special about String as type here. See JacksonAnnotations for details on usage.

Serializing Dates

See JacksonFAQDateHandling.

Custom Serializers

Can I write custom deserializers?

You betcha: check out JacksonHowToCustomSerializers for details.

(and probably also JacksonHowToCustomDeserializers if you need to read data back)

Filtering with Serialization

How can I omit property X from being included in serialization?

There are actually multiple ways, such as:

Serializing, Polymorpic types

Why is there no type information when I serialize Lists/Maps?

If you use something like:

  HashMap<String, MyPOJO> map = ...
  mapper.writeValueAsString(map);

and value type (MyPOJO) has @JsonTypeInfo annotation (or so-called "default typing" indicates it needs to include type information), things should seemingly work. But, alas, as far as Java runtime is concerned, you are NOT serializing a Map<String,MyPOJO, but rather something like Map<?,?! This is due to infamous "Type Erasure", which is due to runtime Class NOT retaining type information -- there is just one class, and not one instance per parameterized version.

For full explanation of what happens, why, and how to resolve this, see JacksonPolymorphicDeserialization, Section 5.1 under "Known Issues".

Serializing, suppressing values (nulls, default values)

Can I omit writing of Bean properties with null value? ("how to prevent writing of null properties", "how to suppress null values")

Yes. As per JacksonAnnotationSerializeNulls, you can use:

  objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
  // or (for older versions):
  objectMapper.configure(SerializationConfig.WRITE_NULL_PROPERTIES, false);

and voila, no more null values. Note that you MUST configure mapper before beans are serialized, since this setting may be cached along with serializers. So setting it too late might prevent change from taking effect.

Alternatively if you only want to change behavior for value of specific type, you can use annotation property:

   @JsonSerialize(include = Inclusion.NON_NULL)
   public class MyTypeWithoutNulls
   {
      public String mayHaveValue; // will not be included if value is null
   }

to achieve the same for the annotated class or property)

Moreover, you can even exclude any properties with default values (values that are set when instance is created with default, no-arg constructor), by calling:

objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT); 

or for specific classes:

   @JsonSerialize(include = Inclusion.NON_DEFAULT)
   public class MyTypeWithoutDefaults
   {
      public int count; // will not be included if value is 0 (default for int)
   }

Serializing, other

What is the simplest way to serialize JSON as a String?

Prior to Jackson 1.3, simplest way is to use java.io.StringWriter:

  StringWriter sw = new StringWriter();
  mapper.writeValue(sw, value);
  String result = sw.toString();

1.3 introduces a new convenience method, so that you can:

  String result = mapper.writeValueAsString(value);

What is the simplest way to serialize JSON as byte[]?

With 1.5: byte[] data = objectMapper.writeValueAsBytes(bean);


Data Binding, reading (de-serialization)

Deserializing simple types

If I want to deserialize simple JSON values (Strings, integer / decimal numbers) into types other than supported by default, do I need to write a custom deserializer?

Not necessarily. If the class to deserialize into has one of:

Jackson will use such method, passing in matching JSON value as argument.

Deserializing Dates

See JacksonFAQDateHandling.

Custom Deserializers

Can I write custom deserializers?

Absolutely. Check out JacksonHowToCustomDeserializers.

(and, related to this JacksonHowToCustomSerializers for serialization side)

Deserializing: unknown properties

By default Jackson throws an exception, if it encounters a JSON property that it can not bind to object property. But if you need to allow such properties in input, you can make Jackson ignore them by:

(for more details, see JacksonHowToIgnoreUnknown)

Deserializing Generic types

Due to Java Type Erasure (losing generics declarations when Classes are compiled), it is NOT possible to specify generic types to bind to. In order to pass full generics type information to, say, bind JSON into List<MyBean>, you have to use methods that take either TypeReference or JavaType. Most commonly former is used; and it is used like so:

List<MyBean> result = mapper.readValue(src, new TypeReference<List<MyBean>>() { });

to use JavaType, you need to construct method by passing java.lang.reflect.Type into TypeFactory (check out JavaDocs for details), or:

List<MyBean> result = mapper.readValue(src, TypeFactory.collectionType(ArrayList.class, MyBean.class));

if you don't like anonymous inner classes (you can similarly construct all kinds of generics types, with TypeFactory.parametericType(...)).

Deserializing Abstract types

If a property has abstract type, how can I make it deserialize into proper concrete type?

There are two distinct cases: if you just have a simple one-to-one mapping from abstract type (interface) into concrete implementation, there are multiple ways to handle this, shown below. If you have multiple implementation types, please look at the next question ("deserializing polymorphic types")

There are multiple ways to indicate specific implementation class of an abstract type:

Deserializing Polymorphic types

But what if there are multiple subtypes for given declared type?

If there are multiple alternate implementations, you need to enable addition of so-called Type Information. For full description, refer to JacksonPolymorphicDeserialization, but there are two basic approaches:

In both cases what happens is that during serialization, a type identifier (class name or logical configurable type name) is included in JSON (using one of multiple placement strategies; most common being as a simple property). And when deserializing, deserializer expects to find this type identifier and will use it to correctly determine expected type to create, and then deserialize instance of that concrete type.

Deserializing, other

Why do I get these java.util.LinkedHashMap objects when deserializing?

If you expect other types (like POJOs), most likely reason is that you are not providing expected type information, and as a result, Jackson assumes what you want is basic java.lang.Object. This can be done by mapping JSON Objects as Java Maps, JSON Array as Java lists, JSON numbers as java.lang.Number and so on.

The most common reason is so-called Java Type Erasure, meaning that generic type information that you think should be available is not. For example, following does NOT work as expected:

  Map&lt;String, MyBean> beansByName = objectMapper.readValue(json, Map.class);

since this is equivalent to asking for binding to Map&lt;?,?>); and type wildcard '?' can only be assumed to be of some Object type.

Instead, you have to specify generic parameters, for example by doing:

  Map&lt;String, MyBean> beansByName = objectMapper.readValue(json, new TypeReference&lt;Map&lt;String, MyBean>>() { });

and then values will be of type MyBean, not LinkedHashMap.

Can I deserialize multiple distinct objects?

Q: (from mailing list)

My JSON payload has multiple objects like so -

{
  "university": {
    "name":"MIT", ...
  },   
  "lecturer": {
    "firstName":"Joe","lastName":"Public", ...
  }
}

I want to de-serialize the JSON object mapped to the key "university" to University.class and I would like to de-serialize the JSON object mapped to key "lecturer" to Lecturer.class. What is the best way to do this?

A:

Two ways to do this:

(a) Create 'dummy' class like

 public class Container {
    public University univ;
    public Lecture lect;
 }

(b) Use JsonParser; skip through JsonToken.START_OBJECT, match JsonToken.FIELD_NAME}}, then call {{{readValueAs() with appropriate type. NOTE: if you use this approach, make sure to use MappingJsonFactory for constructing parser, NOT plain JsonFactory!

Can I use JAXB-style Map/Collection access

(that is: modify Map or Collection properties by calling get, modifying instance directly, without calling matching set method)

Yes: if there is only a getter method for Map/Collection - valued property, and no setter method, Jackson will try to use this mechanism. This behavior can be disabled by disabling DeserializationConfig.USE_GETTERS_AS_SETTERS; although without a setter there will be an exception if such a property was to be deserialized.

Alternatively, if you really want to use this style even if there is a setter method, you will need to suppress use of setter itself. This can be done using @JsonIgnore annotation on setter.


Streaming (incremental) Processing

Problems with String intern()ing

How to avoid "java.lang.OutOfMemoryError: PermGen space" problem?

(modified from a question on Jackson user list)

Q: (from user list)

My application is getting a "java.lang.OutOfMemoryError: PermGen space" error. I tracked this down due to "interned" strings from Jackson while parsing. I believe this is due to some of my input being a map that can have arbitrary key values. What can I do to avoid this?

A:

By default Jackson canonicalizes key names (i.e. tries to ensure all instances of a field name use same String instance); and does this by using String.intern(). Canonicalization is done using a per-JsonFactory shared symbol table; and can help both reduce memory usage and speed up parsing (since can avoid String allocation as well as character decoding in most cases).

However, it is possible to both:

Disabling String intern()ing should be enough to resolve running out of PermGen space; and in general should be enough to avoid excessive memory usage (that is, we have not yet seen any case where it would not). But if you truly think it is not enough, you should try just disabling whole canonicalization. Note that both these options have negative effects on performance in cases where same field names are parsed multiple times (including cases where these are in different documents, but parsers were created by the same factory and thus share the symbol table); effect can be particularly significant if all canonicalization is disabled. Disabling intern()ing should have less effect.

Check out Streaming/incremental API page for even more information.


Tree Model

Node equality?

Can I compare JsonNode instances for equality? (and by extension: "Can I compare full JSON trees by just comparing root nodes")

Yes! JsonNode instances implemented expected deep value comparison, using expected conceptual rules (like: order of JSON Object properties is insignificant for equality, but matters for JSON Arrays).

So you can compare equality of JSON trees by just comparing root nodes like so:

  boolean areEqual = tree1RootNode.equals(tree2RootNode);

(TO BE COMPLETED)

Check out Tree model page for even more information.

Compatibility with Other Things

Non-Java JVM languages

Can Jackson be used from non-Java languages that run on JVM?

Yes. In addition to being used from Java, Jackson has been reported to work from various other JVM-based languages, such as:

(note: would be nice to have links to articles or mailing list messages for these reports)

More specifically, there are now (as of Jackson 1.7) multiple projects that aim to add full support; see Jackson Module Projects page for up to date information.

Alternative data formats

Beyond supporting JSON (and Smile binary format, which is fully JSON compatible), there are related projects that aim to support other data formats. See JacksonOutsideofJSON page for details.

Frameworks

JAX-RS

Can I use Jackson to do JSON serialization with JAX-RS?

Yes. Starting with Jackson 1.0, there is jar (jackson-jaxrs-VERSION.jar) that implements JAX-RS MessageBodyReader and MessageBodyWriter, needed for converting Java beans to/from JSON.

NEW: With version 1.3, there is an improved JAX-RS provider available, org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider; which by default uses both JAXB and Jackson annotations. This can be used in place of earlier JacksonJsonProvider (which is its super-class), and provides extended set of configuration methods. It does depend on features from jax-xc package, so make sure it is also included if using this new provider.

In addition to adding jackson-jaxrs jar (and jackson core and mapper jars it depends on, if not bundled by the JAX-RS implementation), you will also need to register provider. There are 2 ways to do this:

Here's one implementation of the first approach:

import java.util.*;

public final class RestApplication extends javax.ws.rs.core.Application
{
    public Set<Object> getSingletons() {
        HashSet<Object> singletons = new HashSet<Object>();
        singletons.add(new org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider());
        return singletons;
    }
}

Which JAX-RS implementations are Jackson known to work well with?

And there is more on JAX-RS interoperability to learn...

JAXB

Jackson supports some level of interoperability with JAXB API (javax.xml.bin):

Object/Relational Mappers (ORM)

Jackson has been used with some success with:

(might also work with Hibernate, but this has not been verified yet)

As of Jackson 1.7, there is a also a new project, Jackson XML data binding (see JacksonOutsideofJSON for other extension projects) that adds significant subset of JAXB functionality (wrt reading/writing XML) to Jackson.

Spring

Spring-WS / MVC 3.0 has specific support using Jackson for JSON data binding access.

Articles that describe usage:

Mule ESB

Mule ESB version 3.0 will have support for JSON via Jackson, see:

Apache Camel

This article explains how to use Jackson with Apache Camel:

Javascript frameworks

Since Javascript frameworks work on client side, and Jackson on server side, interoperability is usually less problematic. Here some notes on observer interoperability issues.

Ext JS

Default date/time serialization format of Ext JS seems to use ISO-8601 dates without timezone specification. This is problematic since this can be interpreted to mean "local time zone" of the end point, whatever that might be. However, it is possible to re-define this default; for example by: (cut'n pasted from an example sent to Jackson user list by Scott A)

// It's very straightforward to override their treatment of dates:
Ext.util.JSON.encodeDate = function(o)
{
   return '"' + yourEncodingHere + '"';
}

Performance

How does Jackson perform?

Rather nicely. It seems to be the fastest JSON processing package on Java platform, for all processing models. Streaming parser, for example, appears to be 3 - 5x faster than most alternatives (although there are some other fast ones, such as Noggit, but none quite compete). And data binding up to 10x faster as alternatives.

But more useful than our claims are published measurements and performance evaluations. For example:

Members of the Jackson development team have also published some performance measurements:

How can I ensure Jackson runs as fast as possible?

See JacksonBestPracticesPerformance for some suggestions.

Misc

MIME Type for Smile (binary)?

There is no formal registration for Smile content type; but the best current suggestion appears to be application/x-jackson-smile. We suggest you use this type if possible; and when more formal proposal is made, this recommendation will be upgraded as well.


CategoryJackson

JacksonFAQ (last edited 2013-11-27 19:19:00 by TatuSaloranta)

Copyright ©2009 FasterXML, LLC