Class ObjectMapper

  • All Implemented Interfaces:
    Versioned, Serializable
    Direct Known Subclasses:

    public class ObjectMapper
    extends ObjectCodec
    implements Versioned, Serializable
    ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions. It is also highly customizable to work both with different styles of JSON content, and to support more advanced Object concepts such as polymorphism and Object identity. ObjectMapper also acts as a factory for more advanced ObjectReader and ObjectWriter classes. Mapper (and ObjectReaders, ObjectWriters it constructs) will use instances of JsonParser and JsonGenerator for implementing actual reading/writing of JSON. Note that although most read and write methods are exposed through this class, some of the functionality is only exposed via ObjectReader and ObjectWriter: specifically, reading/writing of longer sequences of values is only available through ObjectReader.readValues(InputStream) and ObjectWriter.writeValues(OutputStream).

    Simplest usage is of form:

      final ObjectMapper mapper = new ObjectMapper(); // can use static singleton, inject: just make sure to reuse!
      MyValue value = new MyValue();
      // ... and configure
      File newState = new File("my-stuff.json");
      mapper.writeValue(newState, value); // writes JSON serialization of MyValue instance
      // or, read
      MyValue older = mapper.readValue(new File("my-older-stuff.json"), MyValue.class);
      // Or if you prefer JSON Tree representation:
      JsonNode root = mapper.readTree(newState);
      // and find values by, for example, using a JsonPointer expression:
      int age ="/personal/age").getValueAsInt(); 

    The main conversion API is defined in ObjectCodec, so that implementation details of this class need not be exposed to streaming parser and generator classes. Usage via ObjectCodec is, however, usually only for cases where dependency to ObjectMapper is either not possible (from Streaming API), or undesireable (when only relying on Streaming API).

    Mapper instances are fully thread-safe provided that ALL configuration of the instance occurs before ANY read or write calls. If configuration of a mapper instance is modified after first usage, changes may or may not take effect, and configuration calls themselves may fail. If you need to use different configuration, you have two main possibilities:

    • Construct and use ObjectReader for reading, ObjectWriter for writing. Both types are fully immutable and you can freely create new instances with different configuration using either factory methods of ObjectMapper, or readers/writers themselves. Construction of new ObjectReaders and ObjectWriters is a very light-weight operation so it is usually appropriate to create these on per-call basis, as needed, for configuring things like optional indentation of JSON.
    • If the specific kind of configurability is not available via ObjectReader and ObjectWriter, you may need to use multiple ObjectMapper instead (for example: you cannot change mix-in annotations on-the-fly; or, set of custom (de)serializers). To help with this usage, you may want to use method copy() which creates a clone of the mapper with specific configuration, and allows configuration of the copied instance before it gets used. Note that copy() operation is as expensive as constructing a new ObjectMapper instance: if possible, you should still pool and reuse mappers if you intend to use them for multiple operations.

    Note on caching: root-level deserializers are always cached, and accessed using full (generics-aware) type information. This is different from caching of referenced types, which is more limited and is done only for a subset of all deserializer types. The main reason for difference is that at root-level there is no incoming reference (and hence no referencing property, no referral information or annotations to produce differing deserializers), and that the performance impact greatest at root level (since it'll essentially cache the full graph of deserializers involved).

    Notes on security: use "default typing" feature (see enableDefaultTyping()) is a potential security risk, if used with untrusted content (content generated by untrusted external parties). If so, you may want to construct a custom TypeResolverBuilder implementation to limit possible types to instantiate, (using setDefaultTyping(com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder<?>)).

    See Also:
    Serialized Form