package com.fasterxml.jackson.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

Annotation used to indicate when value of the annotated property (when used for a field, method or constructor parameter), or all properties of the annotated class, is to be serialized. Without annotation property values are always included, but by using this annotation one can specify simple exclusion rules to reduce amount of properties to write out.

Note that the main inclusion criteria (one annotated with value) is checked on Java object level, for the annotated type, and NOT on JSON output -- so even with Include.NON_NULL it is possible that JSON null values are output, if object reference in question is not `null`. An example is AtomicReference instance constructed to reference null value: such a value would be serialized as JSON null, and not filtered out.

To base inclusion on value of contained value(s), you will typically also need to specify content() annotation; for example, specifying only value as Include.NON_EMPTY for a {link java.util.Map} would exclude Maps with no values, but would include Maps with `null` values. To exclude Map with only `null` value, you would use both annotations like so:

public class Bean { @JsonInclude(value=Include.NON_EMPTY, content=Include.NON_NULL) public Map<String,String> entries; } 
Similarly you could Maps that only contain "empty" elements, or "non-default" values (see Include.NON_EMPTY and Include.NON_DEFAULT for more details).

In addition to `Map`s, `content` concept is also supported for referential types (like AtomicReference). Note that `content` is NOT currently (as of Jackson 2.9) supported for arrays or Collections, but supported may be added in future versions.

Since:2.0
/** * Annotation used to indicate when value of the annotated property (when * used for a field, method or constructor parameter), or all * properties of the annotated class, is to be serialized. * Without annotation property values are always included, but by using * this annotation one can specify simple exclusion rules to reduce * amount of properties to write out. *<p> * Note that the main inclusion criteria (one annotated with {@link #value}) * is checked on <b>Java object level</b>, for the annotated type, * and <b>NOT</b> on JSON output -- so even with {@link Include#NON_NULL} * it is possible that JSON null values are output, if object reference * in question is not `null`. An example is {@link java.util.concurrent.atomic.AtomicReference} * instance constructed to reference <code>null</code> value: such a value * would be serialized as JSON null, and not filtered out. *<p> * To base inclusion on value of contained value(s), you will typically also need * to specify {@link #content()} annotation; for example, specifying only * {@link #value} as {@link Include#NON_EMPTY} for a {link java.util.Map} would * exclude <code>Map</code>s with no values, but would include <code>Map</code>s * with `null` values. To exclude Map with only `null` value, you would use both * annotations like so: *<pre> *public class Bean { * {@literal @JsonInclude}(value=Include.NON_EMPTY, content=Include.NON_NULL) * public Map&lt;String,String&gt; entries; *} *</pre> * Similarly you could Maps that only contain * "empty" elements, or "non-default" values (see {@link Include#NON_EMPTY} and * {@link Include#NON_DEFAULT} for more details). *<p> * In addition to `Map`s, `content` concept is also supported for referential * types (like {@link java.util.concurrent.atomic.AtomicReference}). * Note that `content` is NOT currently (as of Jackson 2.9) supported for * arrays or {@link java.util.Collection}s, but supported may be added in * future versions. * * @since 2.0 */
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotation public @interface JsonInclude {
Inclusion rule to use for instances (values) of types (Classes) or properties annotated; defaults to Include.ALWAYS.
/** * Inclusion rule to use for instances (values) of types (Classes) or * properties annotated; defaults to {@link Include#ALWAYS}. */
public Include value() default Include.ALWAYS;
Inclusion rule to use for entries ("content") of annotated Maps and referential types (like AtomicReference); defaults to Include.ALWAYS.
Since:2.5
/** * Inclusion rule to use for entries ("content") of annotated * {@link java.util.Map}s and referential types (like * {@link java.util.concurrent.atomic.AtomicReference}); * defaults to {@link Include#ALWAYS}. * * @since 2.5 */
public Include content() default Include.ALWAYS;
Specifies type of "Filter Object" to use in case value is Include.CUSTOM: if so, an instance is created by calling HandlerInstantiator (of ObjectMapper), which by default simply calls zero-argument constructor of the Filter Class.
Since:2.9
/** * Specifies type of "Filter Object" to use in case * {@link #value} is {@link JsonInclude.Include#CUSTOM}: * if so, an instance is created by calling <code>HandlerInstantiator</code> * (of <code>ObjectMapper</code>), which by default simply calls * zero-argument constructor of the Filter Class. * * @since 2.9 */
public Class<?> valueFilter() default Void.class;
Specifies type of "Filter Object" to use in case content is Include.CUSTOM: if so, an instance is created by calling HandlerInstantiator (of ObjectMapper), which by default simply calls zero-argument constructor of the Filter Class.
Since:2.9
/** * Specifies type of "Filter Object" to use in case * {@link #content} is {@link JsonInclude.Include#CUSTOM}: * if so, an instance is created by calling <code>HandlerInstantiator</code> * (of <code>ObjectMapper</code>), which by default simply calls * zero-argument constructor of the Filter Class. * * @since 2.9 */
public Class<?> contentFilter() default Void.class; /* /********************************************************** /* Value enumerations /********************************************************** */
Enumeration used with JsonInclude to define which properties of Java Beans are to be included in serialization.
/** * Enumeration used with {@link JsonInclude} * to define which properties * of Java Beans are to be included in serialization. */
public enum Include {
Value that indicates that property is to be always included, independent of value of the property.
/** * Value that indicates that property is to be always included, * independent of value of the property. */
ALWAYS,
Value that indicates that only properties with non-null values are to be included.
/** * Value that indicates that only properties with non-null * values are to be included. */
NON_NULL,
Value that indicates that properties are included unless their value is:
  • null
  • "absent" value of a referential type (like Java 8 `Optional`, or {link java.util.concurrent.atomic.AtomicReference}); that is, something that would not deference to a non-null value.
This option is mostly used to work with "Optional"s (Java 8, Guava).
Since:2.6
/** * Value that indicates that properties are included unless their value * is: *<ul> * <li>null</li> * <li>"absent" value of a referential type (like Java 8 `Optional`, or * {link java.util.concurrent.atomic.AtomicReference}); that is, something * that would not deference to a non-null value. * </ul> * This option is mostly used to work with "Optional"s (Java 8, Guava). * * @since 2.6 */
NON_ABSENT,
Value that indicates that only properties with null value, or what is considered empty, are not to be included. Definition of emptiness is data type specific; see below for details on actual handling.

Default emptiness for all types includes:

so that as baseline, "empty" set includes values that would be excluded by both NON_NULL and NON_ABSENT.
Beyond this base, following types have additional empty values:
  • For Collections and Maps, method isEmpty() is called;
  • For Java arrays, empty arrays are ones with length of 0
  • For Java Strings, length() is called, and return value of 0 indicates empty String
and for other types, null values are excluded but other exclusions (if any).

Note that this default handling can be overridden by custom JsonSerializer implementation: if method isEmpty() is overridden, it will be called to see if non-null values are considered empty (null is always considered empty).

Compatibility note: Jackson 2.6 included a wider range of "empty" values than either earlier (up to 2.5) or later (2.7 and beyond) types; specifically:

  • Default values of primitive types (like 0 for `int`/`java.lang.Integer` and `false` for `bool`/`Boolean`)
  • Timestamp 0 for date/time types
With 2.7, definition has been tightened back to only containing types explained above (null, absent, empty String, empty containers), and now extended definition may be specified using NON_DEFAULT.
/** * Value that indicates that only properties with null value, * or what is considered empty, are not to be included. * Definition of emptiness is data type specific; see below * for details on actual handling. *<p> * Default emptiness for all types includes: *<ul> * <li><code>Null</code> values.</li> * <li>"Absent" values (see {@link #NON_ABSENT})</li> *</ul> * so that as baseline, "empty" set includes values that would be * excluded by both {@link #NON_NULL} and {@link #NON_ABSENT}. *<br> * Beyond this base, following types have additional empty values: *<ul> * <li>For {@link java.util.Collection}s and {@link java.util.Map}s, * method <code>isEmpty()</code> is called; * </li> * <li>For Java arrays, empty arrays are ones with length of 0 * </li> * <li>For Java {@link java.lang.String}s, <code>length()</code> is called, * and return value of 0 indicates empty String * </li> * </ul> * and for other types, null values are excluded but other exclusions (if any). *<p> * Note that this default handling can be overridden by custom * <code>JsonSerializer</code> implementation: if method <code>isEmpty()</code> * is overridden, it will be called to see if non-null values are * considered empty (null is always considered empty). *<p> * Compatibility note: Jackson 2.6 included a wider range of "empty" values than * either earlier (up to 2.5) or later (2.7 and beyond) types; specifically: *<ul> * <li>Default values of primitive types (like <code>0</code> for `int`/`java.lang.Integer` * and `false` for `bool`/`Boolean`) * </li> * <li>Timestamp 0 for date/time types * </li> *</ul> * With 2.7, definition has been tightened back to only containing types explained * above (null, absent, empty String, empty containers), and now * extended definition may be specified using {@link #NON_DEFAULT}. */
NON_EMPTY,
Meaning of this setting depends on context: whether annotation is specified for POJO type (class), or not. In latter case annotation is either used as the global default, or as property override.

When used for a POJO, definition is that only values that differ from the default values of POJO properties are included. This is done by creating an instance of POJO using zero-argument constructor, and accessing property values: value is used as the default value by using equals() method, except for the case where property has `null` value in which case straight null check is used.

When NOT used for a POJO (that is, as a global default, or as property override), definition is such that:

  • All values considered "empty" (as per NON_EMPTY) are excluded
  • Primitive/wrapper default values are excluded
  • Date/time values that have timestamp (`long` value of milliseconds since epoch, see Date) of `0L` are excluded
/** * Meaning of this setting depends on context: whether annotation is * specified for POJO type (class), or not. In latter case annotation * is either used as the global default, or as property override. *<p> * When used for a POJO, definition is that only values that differ from * the default values of POJO properties are included. This is done * by creating an instance of POJO using zero-argument constructor, * and accessing property values: value is used as the default value * by using <code>equals()</code> method, except for the case where property * has `null` value in which case straight null check is used. *<p> * When NOT used for a POJO (that is, as a global default, or as property * override), definition is such that: *<ul> * <li>All values considered "empty" (as per {@link #NON_EMPTY}) are excluded</li> * <li>Primitive/wrapper default values are excluded</li> * <li>Date/time values that have timestamp (`long` value of milliseconds since * epoch, see {@link java.util.Date}) of `0L` are excluded</li> * </ul> */
NON_DEFAULT,
Value that indicates that separate `filter` Object (specified by JsonInclude.valueFilter for value itself, and/or JsonInclude.contentFilter for contents of structured types) is to be used for determining inclusion criteria. Filter object's equals() method is called with value to serialize; if it returns true value is excluded (that is, filtered out); if false value is included.
Since:2.9
/** * Value that indicates that separate `filter` Object (specified by * {@link JsonInclude#valueFilter} for value itself, and/or * {@link JsonInclude#contentFilter} for contents of structured types) * is to be used for determining inclusion criteria. * Filter object's <code>equals()</code> method is called with value * to serialize; if it returns <code>true</code> value is <b>excluded</b> * (that is, filtered out); if <code>false</code> value is <b>included</b>. * * @since 2.9 */
CUSTOM,
Pseudo-value used to indicate that the higher-level defaults make sense, to avoid overriding inclusion value. For example, if returned for a property this would use defaults for the class that contains property, if any defined; and if none defined for that, then global serialization inclusion details.
Since:2.6
/** * Pseudo-value used to indicate that the higher-level defaults make * sense, to avoid overriding inclusion value. For example, if returned * for a property this would use defaults for the class that contains * property, if any defined; and if none defined for that, then * global serialization inclusion details. * * @since 2.6 */
USE_DEFAULTS ; } /* /********************************************************** /* Value class used to enclose information /********************************************************** */
Helper class used to contain information from a single JsonInclude annotation.
Since:2.6
/** * Helper class used to contain information from a single {@link JsonInclude} * annotation. * * @since 2.6 */
public static class Value implements JacksonAnnotationValue<JsonInclude>, // since 2.6 java.io.Serializable { private static final long serialVersionUID = 1L; protected final static Value EMPTY = new Value(Include.USE_DEFAULTS, Include.USE_DEFAULTS, null, null); protected final Include _valueInclusion; protected final Include _contentInclusion;
Since:2.9
/** * @since 2.9 */
protected final Class<?> _valueFilter;
Since:2.9
/** * @since 2.9 */
protected final Class<?> _contentFilter; public Value(JsonInclude src) { this(src.value(), src.content(), src.valueFilter(), src.contentFilter()); } protected Value(Include vi, Include ci, Class<?> valueFilter, Class<?> contentFilter) { _valueInclusion = (vi == null) ? Include.USE_DEFAULTS : vi; _contentInclusion = (ci == null) ? Include.USE_DEFAULTS : ci; _valueFilter = (valueFilter == Void.class) ? null : valueFilter; _contentFilter = (contentFilter == Void.class) ? null : contentFilter; } public static Value empty() { return EMPTY; }
Helper method that will try to combine values from two Value instances, using one as base settings, and the other as overrides to use instead of base values when defined; base values are only use if override does not specify a value (matching value is null or logically missing). Note that one or both of value instances may be `null`, directly; if both are `null`, result will also be `null`; otherwise never null.
Since:2.8
/** * Helper method that will try to combine values from two {@link Value} * instances, using one as base settings, and the other as overrides * to use instead of base values when defined; base values are only * use if override does not specify a value (matching value is null * or logically missing). * Note that one or both of value instances may be `null`, directly; * if both are `null`, result will also be `null`; otherwise never null. * * @since 2.8 */
public static Value merge(Value base, Value overrides) { return (base == null) ? overrides : base.withOverrides(overrides); }
Since:2.8
/** * @since 2.8 */
public static Value mergeAll(Value... values) { Value result = null; for (Value curr : values) { if (curr != null) { result = (result == null) ? curr : result.withOverrides(curr); } } return result; } // for JDK serialization protected Object readResolve() { if ((_valueInclusion == Include.USE_DEFAULTS) && (_contentInclusion == Include.USE_DEFAULTS) && (_valueFilter == null) && (_contentFilter == null) ) { return EMPTY; } return this; }
Mutant factory method that merges values of this value with given override values, so that any explicitly defined inclusion in overrides has precedence over settings of this value instance. If no overrides exist will return this instance; otherwise new Value with changed inclusion values.
/** * Mutant factory method that merges values of this value with given override * values, so that any explicitly defined inclusion in overrides has precedence over * settings of this value instance. If no overrides exist will return <code>this</code> * instance; otherwise new {@link Value} with changed inclusion values. */
public Value withOverrides(Value overrides) { if ((overrides == null) || (overrides == EMPTY)) { return this; } Include vi = overrides._valueInclusion; Include ci = overrides._contentInclusion; Class<?> vf = overrides._valueFilter; Class<?> cf = overrides._contentFilter; boolean viDiff = (vi != _valueInclusion) && (vi != Include.USE_DEFAULTS); boolean ciDiff = (ci != _contentInclusion) && (ci != Include.USE_DEFAULTS); boolean filterDiff = (vf != _valueFilter) || (cf != _valueFilter); if (viDiff) { if (ciDiff) { return new Value(vi, ci, vf, cf); } return new Value(vi, _contentInclusion, vf, cf); } else if (ciDiff) { return new Value(_valueInclusion, ci, vf, cf); } else if (filterDiff) { return new Value(_valueInclusion, _contentInclusion, vf, cf); } return this; }
Factory method to use for constructing an instance for components
/** * Factory method to use for constructing an instance for components */
public static Value construct(Include valueIncl, Include contentIncl) { if (((valueIncl == Include.USE_DEFAULTS) || (valueIncl == null)) && ((contentIncl == Include.USE_DEFAULTS) || (contentIncl == null))) { return EMPTY; } return new Value(valueIncl, contentIncl, null, null); }
Factory method to use for constructing an instance for components
Since:2.9
/** * Factory method to use for constructing an instance for components * * @since 2.9 */
public static Value construct(Include valueIncl, Include contentIncl, Class<?> valueFilter, Class<?> contentFilter) { if (valueFilter == Void.class) { valueFilter = null; } if (contentFilter == Void.class) { contentFilter = null; } if (((valueIncl == Include.USE_DEFAULTS) || (valueIncl == null)) && ((contentIncl == Include.USE_DEFAULTS) || (contentIncl == null)) && (valueFilter == null) && (contentFilter == null) ) { return EMPTY; } return new Value(valueIncl, contentIncl, valueFilter, contentFilter); }
Factory method to use for constructing an instance from instance of JsonInclude
/** * Factory method to use for constructing an instance from instance of * {@link JsonInclude} */
public static Value from(JsonInclude src) { if (src == null) { return EMPTY; } Include vi = src.value(); Include ci = src.content(); if ((vi == Include.USE_DEFAULTS) && (ci == Include.USE_DEFAULTS)) { return EMPTY; } Class<?> vf = src.valueFilter(); if (vf == Void.class) { vf = null; } Class<?> cf = src.contentFilter(); if (cf == Void.class) { cf = null; } return new Value(vi, ci, vf, cf); } public Value withValueInclusion(Include incl) { return (incl == _valueInclusion) ? this : new Value(incl, _contentInclusion, _valueFilter, _contentFilter); }
Mutant factory that will either
  • Set value as USE_DEFAULTS and valueFilter to filter (if filter not null); or
  • Set value as ALWAYS (if filter null)
Since:2.9
/** * Mutant factory that will either *<ul> * <li>Set <code>value</code> as <code>USE_DEFAULTS</code> * and <code>valueFilter</code> to <code>filter</code> (if filter not null); * or</li> * <li>Set <code>value</code> as <code>ALWAYS</code> (if filter null) * </li> * </ul> * * @since 2.9 */
public Value withValueFilter(Class<?> filter) { Include incl; if (filter == null || filter == Void.class) { // clear filter incl = Include.USE_DEFAULTS; filter = null; } else { incl = Include.CUSTOM; } return construct(incl, _contentInclusion, filter, _contentFilter); }
Mutant factory that will either
  • Set content as USE_DEFAULTS and contentFilter to filter (if filter not null); or
  • Set content as ALWAYS (if filter null)
Since:2.9
/** * Mutant factory that will either *<ul> * <li>Set <code>content</code> as <code>USE_DEFAULTS</code> * and <code>contentFilter</code> to <code>filter</code> (if filter not null); * or</li> * <li>Set <code>content</code> as <code>ALWAYS</code> (if filter null) * </li> * </ul> * * @since 2.9 */
public Value withContentFilter(Class<?> filter) { Include incl; if (filter == null || filter == Void.class) { // clear filter incl = Include.USE_DEFAULTS; filter = null; } else { incl = Include.CUSTOM; } return construct(_valueInclusion, incl, _valueFilter, filter); } public Value withContentInclusion(Include incl) { return (incl == _contentInclusion) ? this : new Value(_valueInclusion, incl, _valueFilter, _contentFilter); } @Override public Class<JsonInclude> valueFor() { return JsonInclude.class; } public Include getValueInclusion() { return _valueInclusion; } public Include getContentInclusion() { return _contentInclusion; } public Class<?> getValueFilter() { return _valueFilter; } public Class<?> getContentFilter() { return _contentFilter; } @Override public String toString() { StringBuilder sb = new StringBuilder(80); sb.append("JsonInclude.Value(value=") .append(_valueInclusion) .append(",content=") .append(_contentInclusion); if (_valueFilter != null) { sb.append(",valueFilter=").append(_valueFilter.getName()).append(".class"); } if (_contentFilter != null) { sb.append(",contentFilter=").append(_contentFilter.getName()).append(".class"); } return sb.append(')').toString(); } @Override public int hashCode() { return (_valueInclusion.hashCode() << 2) + _contentInclusion.hashCode(); } @Override public boolean equals(Object o) { if (o == this) return true; if (o == null) return false; if (o.getClass() != getClass()) return false; Value other = (Value) o; return (other._valueInclusion == _valueInclusion) && (other._contentInclusion == _contentInclusion) && (other._valueFilter == _valueFilter) && (other._contentFilter == _contentFilter) ; } } }