Jackson ObjectMapper: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(27 intermediate revisions by the same user not shown)
Line 14: Line 14:


With 2.0 and above, <tt>ObjectWriter</tt> and <tt>ObjectReader</tt> can be constructed by <tt>ObjectMapper</tt>. These objects are fully immutable, thread-safe and <font color=darkgray>cheap to create?</font>
With 2.0 and above, <tt>ObjectWriter</tt> and <tt>ObjectReader</tt> can be constructed by <tt>ObjectMapper</tt>. These objects are fully immutable, thread-safe and <font color=darkgray>cheap to create?</font>
=Usage Examples=
{{Internal|Spring Messaging usage of Jackson to Serialize Outgoing Messages|Spring Messaging usage of Jackson to Serialize Outgoing Messages}}


=Configuration=
=Configuration=
Line 51: Line 55:


<syntaxhighlight lang='java'>
<syntaxhighlight lang='java'>
om.configure(MapperFeature.AUTO_DETECT_CREATORS, false);
om.configure(MapperFeature.AUTO_DETECT_CREATORS, true);
</syntaxhighlight>
</syntaxhighlight>


Line 59: Line 63:


<syntaxhighlight lang='java'>
<syntaxhighlight lang='java'>
om.configure(MapperFeature.AUTO_DETECT_FIELDS, false);
om.configure(MapperFeature.AUTO_DETECT_FIELDS, true);
</syntaxhighlight>
</syntaxhighlight>


Line 67: Line 71:


<syntaxhighlight lang='java'>
<syntaxhighlight lang='java'>
om.configure(MapperFeature.AUTO_DETECT_GETTERS, false);
om.configure(MapperFeature.AUTO_DETECT_GETTERS, true);
</syntaxhighlight>
</syntaxhighlight>


====Auto-Detect "is" Getters====
====Auto-Detect "is" Getters====


    /**
This feature that determines whether "is getter" methods are automatically detected based on standard Bean naming convention or not. This feature is enabled by default. If yes, then all public zero-argument methods that start with prefix "is", and whose return type is boolean are considered as "is getters". If disabled, only methods explicitly annotated are considered getters. This feature has lower precedence than per-class annotations, and is only used if there isn't more granular configuration available.
    * Feature that determines whether "is getter" methods are
 
    * automatically detected based on standard Bean naming convention
<syntaxhighlight lang='java'>
    * or not. If yes, then all public zero-argument methods that
om.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
    * start with prefix "is", and whose return type is boolean
</syntaxhighlight>
    * are considered as "is getters".
 
    * If disabled, only methods explicitly annotated are considered getters.
====Auto-Detect Setters====
    *<p>
 
    * Note that this feature has lower precedence than per-class
This feature that determines whether "setter" methods are automatically detected based on standard Bean naming convention or not. This feature is enabled by default. If yes, then all public one-argument methods that start with prefix "set" are considered setters. If disabled, only methods explicitly annotated are considered setters. This feature has lower precedence than per-class annotations, and is only used if there isn't more granular configuration available.
    * annotations, and is only used if there isn't more granular
 
    * configuration available.
<syntaxhighlight lang='java'>
    *<p>
om.configure(MapperFeature.AUTO_DETECT_SETTERS, true);
    * Feature is enabled by default.
</syntaxhighlight>
    */
 
    AUTO_DETECT_IS_GETTERS(true),
====Require Setters for Getters====
 
This feature that determines whether getters (getter methods) can be auto-detected if there is no matching mutator (setter, constructor parameter or field) or not. This feature is disabled by default. If set to true, only getters that match a mutator are auto-discovered; if false, all auto-detectable getters can be discovered.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.REQUIRE_SETTERS_FOR_GETTERS, false);
</syntaxhighlight>
 
====Allow Final Fields as Mutators====
 
This feature determines whether member fields declared as 'final' may be auto-detected to be used mutators (used to change value of the logical* property) or not. This feature is enabled by default. If enabled, 'final' access modifier has no effect, and such fields may be detected according to usual visibility and inference rules; if disabled, such fields are NOT used as mutators except if explicitly annotated for such use.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS, true);
</syntaxhighlight>
 
====Infer Property Mutators====
 
This feature determines whether member mutators (fields and setters) may be "pulled in" even if they are not visible, as long as there is a visible accessor (getter or field) with same name. For example: field "value" may be inferred as mutator, if there is visible or explicitly marked getter "getValue()". The feature is enabled by default. If enabled, inferring is enabled; otherwise (disabled) only visible and explicitly annotated accessors are ever used. 'getters' are never inferred and need to be either visible (including bean-style naming) or explicitly annotated.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.INFER_PROPERTY_MUTATORS, true);
</syntaxhighlight>
 
====Infer Creator from Constructor Properties====
 
This feature that determines handling of <code>java.beans.ConstructorProperties</code> annotation: when enabled, it is considered as alias of <tt>com.fasterxml.jackson.annotation.JsonCreator</tt>, to mean that constructor should be considered a property-based Creator; when disabled, only constructor parameter name information is used, but constructor is NOT considered an explicit Creator (although may be discovered as one using other annotations or heuristics). The feature is mostly used to help interoperability with frameworks like Lombok that may automatically generate <code>ConstructorProperties</code> annotation but without necessarily meaning that constructor should be used as Creator for deserialization. The feature is enabled by default.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES, true);
</syntaxhighlight>
 
===Access Modifier Handling===
 
====Can Override Access Modifiers====
 
This feature determines whether method and field access modifier settings can be overridden when accessing properties. If enabled, method <code>java.lang.reflect.AccessibleObject#setAccessible</code> may be called to enable access to otherwise unaccessible objects. This setting may have significant performance implications, since access override helps remove costly access checks on each and every Reflection access. If you are considering disabling this feature, be sure to verify performance consequences if usage is performance sensitive. Also note that performance effects vary between Java platforms (JavaSE vs Android, for example), as well as JDK versions: older versions seemed to have more significant performance difference. Conversely, on some platforms, it may be necessary to disable this feature as platform does not allow such calls. The feature is enabled by default.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS, true);
</syntaxhighlight>
 
====Override Public Access Modifiers====
 
This feature that determines that forces call to <code>java.lang.reflect.AccessibleObject#setAccessible</code> even for <code>public</code> accessors -- that is, even if no such call is needed from functionality perspective -- if call is allowed (that is, [[#Can_Override_Access_Modifiers|CAN_OVERRIDE_ACCESS_MODIFIERS]] is set to true). The main reason to enable this feature is possible performance improvement as JDK does not have to perform access checks; these checks are otherwise made for all accessors, including public ones, and may result in slower Reflection calls. Exact impact (if any) depends on Java platform (Java SE, Android) as well as JDK version. The feature is enabled by default.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS, true);
</syntaxhighlight>
 
===Type-Handling Features===
 
====Use Static Typing====
 
This feature determines whether the type detection for serialization should be using actual dynamic runtime type, or declared static type. Note that deserialization always uses declared static types since no runtime types are available (as we are creating instances after using type information). This global default value can be overridden at class, method or field level by using <code>JsonSerialize typing</code> annotation property. This feature is disabled by default which means that dynamic runtime types are used (instead of declared static types) for serialization.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.USE_STATIC_TYPING, false);
</syntaxhighlight>


    /**
====Use Base Type as Default Impl====
    * Feature that determines whether "setter" methods are
    * automatically detected based on standard Bean naming convention
    * or not. If yes, then all public one-argument methods that
    * start with prefix "set"
    * are considered setters. If disabled, only methods explicitly
    * annotated are considered setters.
    *<p>
    * Note that this feature has lower precedence than per-class
    * annotations, and is only used if there isn't more granular
    * configuration available.
    *<P>
    * Feature is enabled by default.
    */
    AUTO_DETECT_SETTERS(true),


    /**
This feature that specifies whether the declared base type of a polymorphic value is to be used as the "default" implementation, if no explicit default class is specified via <code>@JsonTypeInfo.defaultImpl</code> annotation. Note that feature only has effect on deserialization of regular polymorphic properties: it does NOT affect non-polymorphic cases, and is unlikely to work with Default Typing. Feature is disabled by default.
    * Feature that determines whether getters (getter methods)
    * can be auto-detected if there is no matching mutator (setter,
    * constructor parameter or field) or not: if set to true,
    * only getters that match a mutator are auto-discovered; if
    * false, all auto-detectable getters can be discovered.
    *<p>
    * Feature is disabled by default.
    */
    REQUIRE_SETTERS_FOR_GETTERS(false),


    /**
<syntaxhighlight lang='java'>
    * Feature that determines whether member fields declared as 'final' may
om.configure(MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL, false);
    * be auto-detected to be used mutators (used to change value of the logical
</syntaxhighlight>
    * property) or not. If enabled, 'final' access modifier has no effect, and
    * such fields may be detected according to usual visibility and inference
    * rules; if disabled, such fields are NOT used as mutators except if
    * explicitly annotated for such use.
    *<p>
    * Feature is enabled by default, for backwards compatibility reasons.
    *
    * @since 2.2
    */
    ALLOW_FINAL_FIELDS_AS_MUTATORS(true),


    /**
===View-Related Features===
    * Feature that determines whether member mutators (fields and
    * setters) may be "pulled in" even if they are not visible,
    * as long as there is a visible accessor (getter or field) with same name.
    * For example: field "value" may be inferred as mutator,
    * if there is visible or explicitly marked getter "getValue()".
    * If enabled, inferring is enabled; otherwise (disabled) only visible and
    * explicitly annotated accessors are ever used.
    *<p>
    * Note that 'getters' are never inferred and need to be either visible (including
    * bean-style naming) or explicitly annotated.
    *<p>
    * Feature is enabled by default.
    *
    * @since 2.2
    */
    INFER_PROPERTY_MUTATORS(true),


    /**
====Default View Inclusion====
    * Feature that determines handling of <code>java.beans.ConstructorProperties<code>
    * annotation: when enabled, it is considered as alias of
    * {@link com.fasterxml.jackson.annotation.JsonCreator}, to mean that constructor
    * should be considered a property-based Creator; when disabled, only constructor
    * parameter name information is used, but constructor is NOT considered an explicit
    * Creator (although may be discovered as one using other annotations or heuristics).
    *<p>
    * Feature is mostly used to help interoperability with frameworks like Lombok
    * that may automatically generate <code>ConstructorProperties</code> annotation
    * but without necessarily meaning that constructor should be used as Creator
    * for deserialization.
    *<p>
    * Feature is enabled by default.
    *
    * @since 2.9
    */
    INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES(true),


    /*
This feature determines whether properties that have no view annotations are included in JSON serialization views. If enabled, non-annotated properties will be included; when disabled, they will be excluded. So this feature changes between "opt-in" (feature disabled) and "opt-out" (feature enabled) modes. Default value is enabled, meaning that non-annotated properties are included in all views if there is no <code>com.fasterxml.jackson.annotation.JsonView</code> annotation. The feature is enabled by default.
    /******************************************************
    /* Access modifier handling
    /******************************************************
    */


    /**
<syntaxhighlight lang='java'>
    * Feature that determines whether method and field access
om.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
    * modifier settings can be overridden when accessing
</syntaxhighlight>
    * properties. If enabled, method
    * {@link java.lang.reflect.AccessibleObject#setAccessible}
    * may be called to enable access to otherwise unaccessible objects.
    *<p>
    * Note that this setting may have significant performance implications,
    * since access override helps remove costly access checks on each
    * and every Reflection access. If you are considering disabling
    * this feature, be sure to verify performance consequences if usage
    * is performance sensitive.
    * Also note that performance effects vary between Java platforms
    * (JavaSE vs Android, for example), as well as JDK versions: older
    * versions seemed to have more significant performance difference.
    *<p>
    * Conversely, on some platforms, it may be necessary to disable this feature
    * as platform does not allow such calls. For example, when developing
    * Applets (or other Java code that runs on tightly restricted sandbox),
    * it may be necessary to disable the feature regardless of performance effects.
    *<p>
    * Feature is enabled by default.
    */
    CAN_OVERRIDE_ACCESS_MODIFIERS(true),


    /**
===Generic Output Features===
    * Feature that determines that forces call to
    * {@link java.lang.reflect.AccessibleObject#setAccessible} even for
    * <code>public</code> accessors -- that is, even if no such call is
    * needed from functionality perspective -- if call is allowed
    * (that is, {@link #CAN_OVERRIDE_ACCESS_MODIFIERS} is set to true).
    * The main reason to enable this feature is possible performance
    * improvement as JDK does not have to perform access checks; these
    * checks are otherwise made for all accessors, including public ones,
    * and may result in slower Reflection calls. Exact impact (if any)
    * depends on Java platform (Java SE, Android) as well as JDK version.
    *<p>
    * Feature is enabled by default, for legacy reasons (it was the behavior
    * until 2.6)
    *
    * @since 2.7
    */
    OVERRIDE_PUBLIC_ACCESS_MODIFIERS(true),


    /*
====Sort Properties Alphabetically====
    /******************************************************
    /* Type-handling features
    /******************************************************
    */


    /**
This feature defines default property serialization order used for POJO fields. It does not apply to Map serialization. If enabled, default ordering is alphabetic. If disabled, order is unspecified (based on what JDK gives us, which may be declaration order, but is not guaranteed). Note that this is just the default behavior, and can be overridden by explicit overrides in classes (for example with  com.fasterxml.jackson.annotation.JsonPropertyOrder annotation. The feature is disabled by default.
    * Feature that determines whether the type detection for
    * serialization should be using actual dynamic runtime type,
    * or declared static type.
    * Note that deserialization always uses declared static types
    * since no runtime types are available (as we are creating
    * instances after using type information).
    *<p>
    * This global default value can be overridden at class, method
    * or field level by using {@link JsonSerialize#typing} annotation
    * property.
    *<p>
    * Feature is disabled by default which means that dynamic runtime types
    * are used (instead of declared static types) for serialization.
    */
    USE_STATIC_TYPING(false),


    /**
<syntaxhighlight lang='java'>
    * Feature that specifies whether the declared base type of a polymorphic value
om.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false);
    * is to be used as the "default" implementation, if no explicit default class
</syntaxhighlight>
    * is specified via {@code @JsonTypeInfo.defaultImpl} annotation.
    *<p>
    * Note that feature only has effect on deserialization of regular polymorphic properties:
    * it does NOT affect non-polymorphic cases, and is unlikely to work with Default Typing.
    *<p>
    * Feature is disabled by default for backwards compatibility.
    *
    * @since 2.9.6
    */
    USE_BASE_TYPE_AS_DEFAULT_IMPL(false),


    /*
===Name-related Features===
    /******************************************************
    /* View-related features
    /******************************************************
    */
   
    /**
    * Feature that determines whether properties that have no view
    * annotations are included in JSON serialization views (see
    * {@link com.fasterxml.jackson.annotation.JsonView} for more
    * details on JSON Views).
    * If enabled, non-annotated properties will be included;
    * when disabled, they will be excluded. So this feature
    * changes between "opt-in" (feature disabled) and
    * "opt-out" (feature enabled) modes.
    *<p>
    * Default value is enabled, meaning that non-annotated
    * properties are included in all views if there is no
    * {@link com.fasterxml.jackson.annotation.JsonView} annotation.
    *<p>
    * Feature is enabled by default.
    */
    DEFAULT_VIEW_INCLUSION(true),
   
    /*
    /******************************************************
    /* Generic output features
    /******************************************************
    */


    /**
====Accept Case Insensitive Properties====
    * Feature that defines default property serialization order used
    * for POJO fields (note: does <b>not</b> apply to {@link java.util.Map}
    * serialization!):
    * if enabled, default ordering is alphabetic (similar to
    * how {@link com.fasterxml.jackson.annotation.JsonPropertyOrder#alphabetic()}
    * works); if disabled, order is unspecified (based on what JDK gives
    * us, which may be declaration order, but is not guaranteed).
    *<p>
    * Note that this is just the default behavior, and can be overridden by
    * explicit overrides in classes (for example with
    * {@link com.fasterxml.jackson.annotation.JsonPropertyOrder} annotation)
    *<p>
    * Feature is disabled by default.
    */
    SORT_PROPERTIES_ALPHABETICALLY(false),


    /*
This feature allows for more forgiving deserialization of incoming JSON. If enabled, the bean properties will be matched using their lower-case equivalents, meaning that any case-combination (incoming and matching names are canonicalized by lower-casing) should work. Note that there is additional performance overhead since incoming property names need to be lower-cased before comparison, for cases where there are upper-case letters. Overhead for names that are already lower-case should be negligible however. The feature is disabled by default.
    /******************************************************
    /* Name-related features
    /******************************************************
    */


    /**
<syntaxhighlight lang='java'>
    * Feature that will allow for more forgiving deserialization of incoming JSON.
om.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, false);
    * If enabled, the bean properties will be matched using their lower-case equivalents,
</syntaxhighlight>
    * meaning that any case-combination (incoming and matching names are canonicalized
    * by lower-casing) should work.
    *<p>
    * Note that there is additional performance overhead since incoming property
    * names need to be lower-cased before comparison, for cases where there are upper-case
    * letters. Overhead for names that are already lower-case should be negligible however.
    *<p>
    * Feature is disabled by default.
    *
    * @since 2.5
    */
    ACCEPT_CASE_INSENSITIVE_PROPERTIES(false),


====Accept Case Insensitive Enums====


    /**
This feature determines if Enum deserialization should be case sensitive or not. If enabled, Enum deserialization will ignore case, that is, case of incoming String value and enum id (dependant on other settings, either "name()", "toString()", or explicit override) do not need to match. The feature is disabled by default.
    * Feature that determines if Enum deserialization should be case sensitive or not.
    * If enabled, Enum deserialization will ignore case, that is, case of incoming String
    * value and enum id (dependant on other settings, either `name()`, `toString()`, or
    * explicit override) do not need to match.
    * <p>
    * Feature is disabled by default.
    *
    * @since 2.9
    */
    ACCEPT_CASE_INSENSITIVE_ENUMS(false),


    /**
<syntaxhighlight lang='java'>
    * Feature that can be enabled to make property names be
om.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, false);
    * overridden by wrapper name (usually detected with annotations
</syntaxhighlight>
    * as defined by {@link AnnotationIntrospector#findWrapperName}.
    * If enabled, all properties that have associated non-empty Wrapper
    * name will use that wrapper name instead of property name.
    * If disabled, wrapper name is only used for wrapping (if anything).
    *<p>
    * Feature is disabled by default.
    *
    * @since 2.1
    */
    USE_WRAPPER_NAME_AS_PROPERTY_NAME(false),


    /**
====Use Wrapper Name as Property Name====
    * Feature that may be enabled to enforce strict compatibility with
    * Bean name introspection, instead of slightly different mechanism
    * Jackson defaults to.
    * Specific difference is that Jackson always lower cases leading upper-case
    * letters, so "getURL()" becomes "url" property; whereas standard Bean
    * naming <b>only</b> lower-cases the first letter if it is NOT followed by
    * another upper-case letter (so "getURL()" would result in "URL" property).
    *<p>
    * Feature is disabled by default for backwards compatibility purposes: earlier
    * Jackson versions used Jackson's own mechanism.
    *
    * @since 2.5
    */
    USE_STD_BEAN_NAMING(false),


    /**
This feature can be enabled to make property names be overridden by wrapper name (usually detected with annotations as defined by <code>AnnotationIntrospector#findWrapperName</code>. If enabled, all properties that have associated non-empty Wrapper name will use that wrapper name instead of property name. If disabled, wrapper name is only used for wrapping (if anything). The feature is disabled by default.
    * Feature that when enabled will allow explicitly named properties (i.e., fields or methods
    * annotated with {@link com.fasterxml.jackson.annotation.JsonProperty}("explicitName")) to
    * be re-named by a {@link PropertyNamingStrategy}, if one is configured.
    * <p>
    * Feature is disabled by default.
    *
    * @since 2.7
    */
    ALLOW_EXPLICIT_PROPERTY_RENAMING(false),


    /*
<syntaxhighlight lang='java'>
    /******************************************************
om.configure(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME, false);
    /* Coercion features
</syntaxhighlight>
    /******************************************************
    */


    /**
====Use Standard Bean Naming====
    * Feature that determines whether coercions from secondary representations are allowed
    * for simple non-textual scalar types: numbers and booleans. This includes `primitive`
    * types and their wrappers, but excludes `java.lang.String` and date/time types.
    *<p>
    * When feature is disabled, only strictly compatible input may be bound: numbers for
    * numbers, boolean values for booleans. When feature is enabled, conversions from
    * JSON String are allowed, as long as textual value matches (for example, String
    * "true" is allowed as equivalent of JSON boolean token `true`; or String "1.0"
    * for `double`).
    *<p>
    * Note that it is possible that other configurability options can override this
    * in closer scope (like on per-type or per-property basis); this is just the global
    * default.
    *<p>
    * Feature is enabled by default (for backwards compatibility since this was the
    * default behavior)
    *
    * @since 2.9
    */
    ALLOW_COERCION_OF_SCALARS(true),


    /*
This feature that may be enabled to enforce strict compatibility with Bean name introspection, instead of slightly different mechanism Jackson defaults to. Specific difference is that Jackson always lower cases leading upper-case letters, so "getURL()" becomes "url" property; whereas standard Bean naming <b>only</b> lower-cases the first letter if it is NOT followed by another upper-case letter (so "getURL()" would result in "URL" property). The feature is disabled by default.
    /******************************************************
    /* Other features
    /******************************************************
    */


    /**
<syntaxhighlight lang='java'>
    * Feature that determines whether multiple registrations of same module
om.configure(MapperFeature.USE_STD_BEAN_NAMING, false);
    * should be ignored or not; if enabled, only the first registration call
</syntaxhighlight>
    * results in module being called, and possible duplicate calls are silently
    * ignored; if disabled, no checking is done and all registration calls are
    * dispatched to module.
    *<p>
    * Definition of "same module" is based on using {@link Module#getTypeId()};
    * modules with same non-null <code>type id</code> are considered same for
    * purposes of duplicate registration. This also avoids having to keep track
    * of actual module instances; only ids will be kept track of (and only if
    * this feature is enabled).
    *<p>
    * Feature is enabled by default.
    *
    * @since 2.5
    */
    IGNORE_DUPLICATE_MODULE_REGISTRATIONS(true),


    /**
====Use Explicit Property Renaming====
    * Setting that determines what happens if an attempt is made to explicitly
    * "merge" value of a property, where value does not support merging; either
    * merging is skipped and new value is created (<code>true</code>) or
    * an exception is thrown (false).
    *<p>
    * Feature is disabled by default since non-mergeable property types are ignored
    * even if defaults call for merging, and usually explicit per-type or per-property
    * settings for such types should result in an exception.
    *
    * @since 2.9
    */
    IGNORE_MERGE_FOR_UNMERGEABLE(true)


    ;
This feature that when enabled will allow explicitly named properties (i.e., fields or methods annotated with JsonProperty("explicitName") to be re-named by a PropertyNamingStrategy, if one is configured. The feature is disabled by default.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature. ALLOW_EXPLICIT_PROPERTY_RENAMING, false);
</syntaxhighlight>
 
===Coercion Features===
 
====Allow Coercion of Scalars====
 
This feature that determines whether coercions from secondary representations are allowed for simple non-textual scalar types: numbers and booleans. This includes "primitive" types and their wrappers, but excludes "java.lang.String" and date/time types. When the feature is disabled, only strictly compatible input may be bound: numbers for numbers, boolean values for booleans. When feature is enabled, conversions from JSON String are allowed, as long as textual value matches (for example, String "true" is allowed as equivalent of JSON boolean token "true"; or String "1.0" for "double"). Note that it is possible that other configurability options can override this in closer scope (like on per-type or per-property basis); this is just the global default. The feature is enabled by default.
<syntaxhighlight lang='java'>
om.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, true);
</syntaxhighlight>
 
===Other Features===
 
====Ignore Duplicate Module Registration====
 
This feature determines whether multiple registrations of same module should be ignored or not. The feature is enabled by default. If enabled, only the first registration call results in module being called, and possible duplicate calls are silently ignored; if disabled, no checking is done and all registration calls are dispatched to module. Definition of "same module" is based on using <tt>Module#getTypeId()</tt> modules with same non-null <code>type id</code> are considered same for purposes of duplicate registration. This also avoids having to keep track of actual module instances; only ids will be kept track of (and only if this feature is enabled).
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS, true);
</syntaxhighlight>
 
====Ignore Merge for Unmergeable====
 
This feature determines what happens if an attempt is made to explicitly "merge" value of a property, where value does not support merging; either merging is skipped and new value is created (<code>true</code>) or an exception is thrown (false). The feature is disabled by default since non-mergeable property types are ignored even if defaults call for merging, and usually explicit per-type or per-property settings for such types should result in an exception.
 
<syntaxhighlight lang='java'>
om.configure(MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE, false);
</syntaxhighlight>


==Serialization Features==
==Serialization Features==
Line 460: Line 262:


====Writing Date Keys as Timestamps====
====Writing Date Keys as Timestamps====
====Writing or Not Null Fields====
SerializationFeature.WRITE_NULL_MAP_VALUES: true or false. This is deprecated since 2.9, and it does not seem to work. Preventing inclusion of null fields is implemented with @JsonInclude:
{{Internal|@JsonInclude|@JsonInclude}}


==Deserialization Features==
==Deserialization Features==
Line 479: Line 286:
import com.fasterxml.jackson.databind.util.StdDateFormat;
import com.fasterxml.jackson.databind.util.StdDateFormat;


objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// setting SerializationFeature.WRITE_DATES_AS_TIMESTAMPS is actually not necessary
// objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
 
objectMapper.setDateFormat(new StdDateFormat());
objectMapper.setDateFormat(new StdDateFormat());
</syntaxhighlight>
</syntaxhighlight>


<code>StdDateFormat</code> is configured by default, and assumes an UTC time zone.
Alternatively, ISO8601 UTC can be specified globally per ObjectMapper instance as follows:
<syntaxhighlight lang='java'>
DateFormat iso8601_UTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
iso8601_UTC.setTimeZone(TimeZone.getTimeZone("UTC"));
objectMapper.setDateFormat(iso8601_UTC);
</syntaxhighlight>
Also see [[#Writing_Date_Objects_as_Numeric_POSIX_Timestamps|Writing Date Objects as Numeric POSIX Timestamps]] above.
Also see [[#Writing_Date_Objects_as_Numeric_POSIX_Timestamps|Writing Date Objects as Numeric POSIX Timestamps]] above.
This methods allows formatting all Date fields in the structure of an object in bulk. To format individual fields, use [[@JsonFormat]] annotation as shown here: {{Internal|@JsonFormat#Formatting_Date|Formatting Individual Date Fields with @JsonFormat}}


More: {{External|[https://www.baeldung.com/jackson-serialize-dates Jackson Serialize Dates on Baeldung]}}
More: {{External|[https://www.baeldung.com/jackson-serialize-dates Jackson Serialize Dates on Baeldung]}}
=Implementation Details=
{{Internal|ObjectMapper Implementation Details|ObjectMapper Implementation Details}}

Latest revision as of 19:37, 30 December 2018

Internal

Overview

Thread Safety

ObjectMapper is thread safe, so it does not have to be created for each request that needs serialization/deserialization.

It is recommended to declare a static ObjectMapper instance that should be shared as much as possible.

The only problem with this approach is that the configuration of the mapper cannot be changed after it was shared, otherwise clients will rely on invalid assumptions,

With 2.0 and above, ObjectWriter and ObjectReader can be constructed by ObjectMapper. These objects are fully immutable, thread-safe and cheap to create?

Usage Examples

Spring Messaging usage of Jackson to Serialize Outgoing Messages

Configuration

Mapper Features

General Introspection Features

Annotation Use

ObjectMapper can be configured to use or not annotation introspection. By default is true.

om.configure(MapperFeature.USE_ANNOTATIONS, true);

Use Getters as Setters

This feature determines whether the "getter" methods that handle Collections and Maps can be used for purpose of getting a reference to a Collection and Map to modify the property, without requiring a setter method. This is similar to how JAXB framework sets Collections and Maps. Note that such getters-as-setters methods have lower precedence than setters, so they are only used if no setter is found for the Map/Collection property. The feature is enabled by default.

om.configure(MapperFeature.USE_GETTERS_AS_SETTERS, true);

Propagate Transient Marker

This feature determines how transient modifier for fields is handled: if disabled, it is only taken to mean exclusion of the field as accessor; if true, it is taken to imply removal of the whole property. Feature is disabled by default, meaning that existence of transient for a field does not cause Jackson to ignore getters or setters just ignoring the use of field for access.

om.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, false);

Introspection-Based Property Auto-Detection

Auto-Detect Creators

This feature determines whether "creator" methods are automatically detected by consider public constructors, and static single argument methods with name "valueOf". The feature is enabled by default. If disabled, only methods explicitly annotated are considered creator methods, except for the no-arg default constructor which is always considered a factory method. This feature has lower precedence than per-class annotations, and is only used if there isn't more granular configuration available.

om.configure(MapperFeature.AUTO_DETECT_CREATORS, true);

Auto-Detect Fields

This feature determines whether non-static fields are recognized as properties. The feature is enabled by default. If yes, then all public member fields are considered as properties. If disabled, only fields explicitly annotated are considered property fields. This feature has lower precedence than per-class annotations, and is only used if there isn't more granular configuration available.

om.configure(MapperFeature.AUTO_DETECT_FIELDS, true);

Auto-Detect Getters

This feature determines whether regular "getter" methods are automatically detected based on standard Bean naming convention or not. The feature is enabled by default. If yes, then all public zero-argument methods that start with prefix "get" are considered as getters. If disabled, only methods explicitly annotated are considered getters. This configuration does not refer to "is" getters. See Auto-Detect "is" Getters. Note that this feature has lower precedence than per-class annotations, and is only used if there isn't more granular configuration available.

om.configure(MapperFeature.AUTO_DETECT_GETTERS, true);

Auto-Detect "is" Getters

This feature that determines whether "is getter" methods are automatically detected based on standard Bean naming convention or not. This feature is enabled by default. If yes, then all public zero-argument methods that start with prefix "is", and whose return type is boolean are considered as "is getters". If disabled, only methods explicitly annotated are considered getters. This feature has lower precedence than per-class annotations, and is only used if there isn't more granular configuration available.

om.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);

Auto-Detect Setters

This feature that determines whether "setter" methods are automatically detected based on standard Bean naming convention or not. This feature is enabled by default. If yes, then all public one-argument methods that start with prefix "set" are considered setters. If disabled, only methods explicitly annotated are considered setters. This feature has lower precedence than per-class annotations, and is only used if there isn't more granular configuration available.

om.configure(MapperFeature.AUTO_DETECT_SETTERS, true);

Require Setters for Getters

This feature that determines whether getters (getter methods) can be auto-detected if there is no matching mutator (setter, constructor parameter or field) or not. This feature is disabled by default. If set to true, only getters that match a mutator are auto-discovered; if false, all auto-detectable getters can be discovered.

om.configure(MapperFeature.REQUIRE_SETTERS_FOR_GETTERS, false);

Allow Final Fields as Mutators

This feature determines whether member fields declared as 'final' may be auto-detected to be used mutators (used to change value of the logical* property) or not. This feature is enabled by default. If enabled, 'final' access modifier has no effect, and such fields may be detected according to usual visibility and inference rules; if disabled, such fields are NOT used as mutators except if explicitly annotated for such use.

om.configure(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS, true);

Infer Property Mutators

This feature determines whether member mutators (fields and setters) may be "pulled in" even if they are not visible, as long as there is a visible accessor (getter or field) with same name. For example: field "value" may be inferred as mutator, if there is visible or explicitly marked getter "getValue()". The feature is enabled by default. If enabled, inferring is enabled; otherwise (disabled) only visible and explicitly annotated accessors are ever used. 'getters' are never inferred and need to be either visible (including bean-style naming) or explicitly annotated.

om.configure(MapperFeature.INFER_PROPERTY_MUTATORS, true);

Infer Creator from Constructor Properties

This feature that determines handling of java.beans.ConstructorProperties annotation: when enabled, it is considered as alias of com.fasterxml.jackson.annotation.JsonCreator, to mean that constructor should be considered a property-based Creator; when disabled, only constructor parameter name information is used, but constructor is NOT considered an explicit Creator (although may be discovered as one using other annotations or heuristics). The feature is mostly used to help interoperability with frameworks like Lombok that may automatically generate ConstructorProperties annotation but without necessarily meaning that constructor should be used as Creator for deserialization. The feature is enabled by default.

om.configure(MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES, true);

Access Modifier Handling

Can Override Access Modifiers

This feature determines whether method and field access modifier settings can be overridden when accessing properties. If enabled, method java.lang.reflect.AccessibleObject#setAccessible may be called to enable access to otherwise unaccessible objects. This setting may have significant performance implications, since access override helps remove costly access checks on each and every Reflection access. If you are considering disabling this feature, be sure to verify performance consequences if usage is performance sensitive. Also note that performance effects vary between Java platforms (JavaSE vs Android, for example), as well as JDK versions: older versions seemed to have more significant performance difference. Conversely, on some platforms, it may be necessary to disable this feature as platform does not allow such calls. The feature is enabled by default.

om.configure(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS, true);

Override Public Access Modifiers

This feature that determines that forces call to java.lang.reflect.AccessibleObject#setAccessible even for public accessors -- that is, even if no such call is needed from functionality perspective -- if call is allowed (that is, CAN_OVERRIDE_ACCESS_MODIFIERS is set to true). The main reason to enable this feature is possible performance improvement as JDK does not have to perform access checks; these checks are otherwise made for all accessors, including public ones, and may result in slower Reflection calls. Exact impact (if any) depends on Java platform (Java SE, Android) as well as JDK version. The feature is enabled by default.

om.configure(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS, true);

Type-Handling Features

Use Static Typing

This feature determines whether the type detection for serialization should be using actual dynamic runtime type, or declared static type. Note that deserialization always uses declared static types since no runtime types are available (as we are creating instances after using type information). This global default value can be overridden at class, method or field level by using JsonSerialize typing annotation property. This feature is disabled by default which means that dynamic runtime types are used (instead of declared static types) for serialization.

om.configure(MapperFeature.USE_STATIC_TYPING, false);

Use Base Type as Default Impl

This feature that specifies whether the declared base type of a polymorphic value is to be used as the "default" implementation, if no explicit default class is specified via @JsonTypeInfo.defaultImpl annotation. Note that feature only has effect on deserialization of regular polymorphic properties: it does NOT affect non-polymorphic cases, and is unlikely to work with Default Typing. Feature is disabled by default.

om.configure(MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL, false);

View-Related Features

Default View Inclusion

This feature determines whether properties that have no view annotations are included in JSON serialization views. If enabled, non-annotated properties will be included; when disabled, they will be excluded. So this feature changes between "opt-in" (feature disabled) and "opt-out" (feature enabled) modes. Default value is enabled, meaning that non-annotated properties are included in all views if there is no com.fasterxml.jackson.annotation.JsonView annotation. The feature is enabled by default.

om.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);

Generic Output Features

Sort Properties Alphabetically

This feature defines default property serialization order used for POJO fields. It does not apply to Map serialization. If enabled, default ordering is alphabetic. If disabled, order is unspecified (based on what JDK gives us, which may be declaration order, but is not guaranteed). Note that this is just the default behavior, and can be overridden by explicit overrides in classes (for example with com.fasterxml.jackson.annotation.JsonPropertyOrder annotation. The feature is disabled by default.

om.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false);

Name-related Features

Accept Case Insensitive Properties

This feature allows for more forgiving deserialization of incoming JSON. If enabled, the bean properties will be matched using their lower-case equivalents, meaning that any case-combination (incoming and matching names are canonicalized by lower-casing) should work. Note that there is additional performance overhead since incoming property names need to be lower-cased before comparison, for cases where there are upper-case letters. Overhead for names that are already lower-case should be negligible however. The feature is disabled by default.

om.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, false);

Accept Case Insensitive Enums

This feature determines if Enum deserialization should be case sensitive or not. If enabled, Enum deserialization will ignore case, that is, case of incoming String value and enum id (dependant on other settings, either "name()", "toString()", or explicit override) do not need to match. The feature is disabled by default.

om.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, false);

Use Wrapper Name as Property Name

This feature can be enabled to make property names be overridden by wrapper name (usually detected with annotations as defined by AnnotationIntrospector#findWrapperName. If enabled, all properties that have associated non-empty Wrapper name will use that wrapper name instead of property name. If disabled, wrapper name is only used for wrapping (if anything). The feature is disabled by default.

om.configure(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME, false);

Use Standard Bean Naming

This feature that may be enabled to enforce strict compatibility with Bean name introspection, instead of slightly different mechanism Jackson defaults to. Specific difference is that Jackson always lower cases leading upper-case letters, so "getURL()" becomes "url" property; whereas standard Bean naming only lower-cases the first letter if it is NOT followed by another upper-case letter (so "getURL()" would result in "URL" property). The feature is disabled by default.

om.configure(MapperFeature.USE_STD_BEAN_NAMING, false);

Use Explicit Property Renaming

This feature that when enabled will allow explicitly named properties (i.e., fields or methods annotated with JsonProperty("explicitName") to be re-named by a PropertyNamingStrategy, if one is configured. The feature is disabled by default.

om.configure(MapperFeature. ALLOW_EXPLICIT_PROPERTY_RENAMING, false);

Coercion Features

Allow Coercion of Scalars

This feature that determines whether coercions from secondary representations are allowed for simple non-textual scalar types: numbers and booleans. This includes "primitive" types and their wrappers, but excludes "java.lang.String" and date/time types. When the feature is disabled, only strictly compatible input may be bound: numbers for numbers, boolean values for booleans. When feature is enabled, conversions from JSON String are allowed, as long as textual value matches (for example, String "true" is allowed as equivalent of JSON boolean token "true"; or String "1.0" for "double"). Note that it is possible that other configurability options can override this in closer scope (like on per-type or per-property basis); this is just the global default. The feature is enabled by default.

om.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, true);

Other Features

Ignore Duplicate Module Registration

This feature determines whether multiple registrations of same module should be ignored or not. The feature is enabled by default. If enabled, only the first registration call results in module being called, and possible duplicate calls are silently ignored; if disabled, no checking is done and all registration calls are dispatched to module. Definition of "same module" is based on using Module#getTypeId() modules with same non-null type id are considered same for purposes of duplicate registration. This also avoids having to keep track of actual module instances; only ids will be kept track of (and only if this feature is enabled).

om.configure(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS, true);

Ignore Merge for Unmergeable

This feature determines what happens if an attempt is made to explicitly "merge" value of a property, where value does not support merging; either merging is skipped and new value is created (true) or an exception is thrown (false). The feature is disabled by default since non-mergeable property types are ignored even if defaults call for merging, and usually explicit per-type or per-property settings for such types should result in an exception.

om.configure(MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE, false);

Serialization Features

Writing Date Objects as Numeric POSIX Timestamps

This feature determines whether Date and date/time values (java.util.Calendar} are to be serialized as numeric millisecond POSIX timestamps. The feature is enabled by default.

If disabled, the timestamps are rendered in a textual representation. The actual format is one returned by a call to com.fasterxml.jackson.databind.SerializationConfig.getDateFormat(). The default setting is com.fasterxml.jackson.databind.util.StdDateFormat, which corresponds to format String of "yyyy-MM-dd'T'HH:mm:ss.SSSZ". Whether this feature affects handling of other date-related types depend on handlers of those types, although ideally they should use this feature. If a Map keys are Date types, their serialization is controlled by the WRITE_DATE_KEYS_AS_TIMESTAMPS configuration feature.

om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);

Also see Specifying a Date Format below.

Writing Date Keys as Timestamps

Writing or Not Null Fields

SerializationFeature.WRITE_NULL_MAP_VALUES: true or false. This is deprecated since 2.9, and it does not seem to work. Preventing inclusion of null fields is implemented with @JsonInclude:

@JsonInclude

Deserialization Features

Fail on Ignored Properties

This feature determines what happens when a property that has been explicitly marked as ignorable is encountered in input: if feature is enabled, JsonMappingException is thrown; if false, property is quietly skipped. The feature is disabled by default so that no exception is thrown. Another way to look at it is as configuration to ignore fields that appear in the JSON serialized format, but are not declared as members in the type. The same effect can be achieved by annotating the type with @JsonIgnoreProperties

om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Specifying a Date Format

ISO 8601 date and time format can be automatically handled (converted from and to) by the ObjectMapper, as follows:

import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.util.StdDateFormat;

// setting SerializationFeature.WRITE_DATES_AS_TIMESTAMPS is actually not necessary
// objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

objectMapper.setDateFormat(new StdDateFormat());

StdDateFormat is configured by default, and assumes an UTC time zone.

Alternatively, ISO8601 UTC can be specified globally per ObjectMapper instance as follows:

DateFormat iso8601_UTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
iso8601_UTC.setTimeZone(TimeZone.getTimeZone("UTC"));
objectMapper.setDateFormat(iso8601_UTC);

Also see Writing Date Objects as Numeric POSIX Timestamps above.

This methods allows formatting all Date fields in the structure of an object in bulk. To format individual fields, use @JsonFormat annotation as shown here:

Formatting Individual Date Fields with @JsonFormat

More:

Jackson Serialize Dates on Baeldung

Implementation Details

ObjectMapper Implementation Details