package com.fasterxml.jackson.databind; import java.io.IOException; import java.util.Iterator; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.ser.PropertyWriter; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.NameTransformer; /** * Abstract class that defines API used by {@link ObjectMapper} (and * other chained {@link JsonSerializer}s too) to serialize Objects of * arbitrary types into JSON, using provided {@link JsonGenerator}. * {@link com.fasterxml.jackson.databind.ser.std.StdSerializer} instead * of this class, since it will implement many of optional * methods of this class. *
* NOTE: various serialize
methods are never (to be) called
* with null values -- caller must handle null values, usually
* by calling {@link SerializerProvider#findNullValueSerializer} to obtain
* serializer to use.
* This also means that custom serializers cannot be directly used to change
* the output to produce when serializing null values.
*
* If serializer is an aggregate one -- meaning it delegates handling of some * of its contents by using other serializer(s) -- it typically also needs * to implement {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer}, * which can locate secondary serializers needed. This is important to allow dynamic * overrides of serializers; separate call interface is needed to separate * resolution of secondary serializers (which may have cyclic link back * to serializer itself, directly or indirectly). *
* In addition, to support per-property annotations (to configure aspects * of serialization on per-property basis), serializers may want * to implement * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer}, * which allows specialization of serializers: call to * {@link com.fasterxml.jackson.databind.ser.ContextualSerializer#createContextual} * is passed information on property, and can create a newly configured * serializer for handling that particular property. *
* If both
* {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer} and
* {@link com.fasterxml.jackson.databind.ser.ContextualSerializer}
* are implemented, resolution of serializers occurs before
* contextualization.
*/
public abstract class JsonSerializer
* Default implementation just returns serializer as-is,
* indicating that no unwrapped variant exists
*
* @param unwrapper Name transformation to use to convert between names
* of unwrapper properties
*/
public JsonSerializer
* Default implementation simply returns
* Default implementation will throw {@link UnsupportedOperationException}
* to indicate that proper type handling needs to be implemented.
*
* For simple datatypes written as a single scalar value (JSON String, Number, Boolean),
* implementation would look like:
*
* Default implementation will return null, which essentially means
* same as returning
*/
public Class
* Default implementation will consider only null values to be empty.
*
* @deprecated Since 2.5 Use {@link #isEmpty(SerializerProvider, Object)} instead;
* will be removed from 3.0
*/
@Deprecated
public boolean isEmpty(T value) {
return isEmpty(null, value);
}
/**
* Method called to check whether given serializable value is
* considered "empty" value (for purposes of suppressing serialization
* of empty values).
*
* Default implementation will consider only null values to be empty.
*
* NOTE: replaces {@link #isEmpty(Object)}, which was deprecated in 2.5
*
* @since 2.5
*/
public boolean isEmpty(SerializerProvider provider, T value) {
return (value == null);
}
/**
* Method that can be called to see whether this serializer instance
* will use Object Id to handle cyclic references.
*/
public boolean usesObjectId() {
return false;
}
/**
* Accessor for checking whether this serializer is an
* "unwrapping" serializer; this is necessary to know since
* it may also require caller to suppress writing of the
* leading property name.
*/
public boolean isUnwrappingSerializer() {
return false;
}
/**
* Accessor that can be used to determine if this serializer uses
* another serializer for actual serialization, by delegating
* calls. If so, will return immediate delegate (which itself may
* delegate to further serializers); otherwise will return null.
*
* @return Serializer this serializer delegates calls to, if null;
* null otherwise.
*
* @since 2.1
*/
public JsonSerializer> getDelegatee() {
return null;
}
/**
* Accessor for iterating over logical properties that the type
* handled by this serializer has, from serialization perspective.
* Actual type of properties, if any, will be
* {@link com.fasterxml.jackson.databind.ser.BeanPropertyWriter}.
* Of standard Jackson serializers, only {@link com.fasterxml.jackson.databind.ser.BeanSerializer}
* exposes properties.
*
* @since 2.6
*/
public Iterator
* Specifically, this class is to be used as the marker for
* annotation {@link com.fasterxml.jackson.databind.annotation.JsonSerialize}.
*/
public abstract static class None
extends JsonSerializerfilterId
) is to be used for
* serialization.
*this
; sub-classes that do support
* filtering will need to create and return new instance if filter changes.
*
* @since 2.6
*/
public JsonSerializer> withFilterId(Object filterId) {
return this;
}
/*
/**********************************************************
/* Serialization methods
/**********************************************************
*/
/**
* Method that can be called to ask implementation to serialize
* values of type this serializer handles.
*
* @param value Value to serialize; can not be null.
* @param gen Generator used to output resulting Json content
* @param serializers Provider that can be used to get serializers for
* serializing Objects value contains, if any.
*/
public abstract void serialize(T value, JsonGenerator gen, SerializerProvider serializers)
throws IOException;
/**
* Method that can be called to ask implementation to serialize
* values of type this serializer handles, using specified type serializer
* for embedding necessary type information.
*
* // note: method to call depends on whether this type is serialized as JSON scalar, object or Array!
* typeSer.writeTypePrefixForScalar(value, gen);
* serialize(value, gen, provider);
* typeSer.writeTypeSuffixForScalar(value, gen);
*
* and implementations for type serialized as JSON Arrays or Objects would differ slightly,
* as START-ARRAY
/END-ARRAY
and
* START-OBJECT
/END-OBJECT
pairs
* need to be properly handled with respect to serializing of contents.
*
* @param value Value to serialize; can not be null.
* @param gen Generator used to output resulting Json content
* @param serializers Provider that can be used to get serializers for
* serializing Objects value contains, if any.
* @param typeSer Type serializer to use for including type information
*/
public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers,
TypeSerializer typeSer)
throws IOException
{
Class> clz = handledType();
if (clz == null) {
clz = value.getClass();
}
serializers.reportBadDefinition(clz, String.format(
"Type id handling not implemented for type %s (by serializer of type %s)",
clz.getName(), getClass().getName()));
}
/*
/**********************************************************
/* Other accessors
/**********************************************************
*/
/**
* Method for accessing type of Objects this serializer can handle.
* Note that this information is not guaranteed to be exact -- it
* may be a more generic (super-type) -- but it should not be
* incorrect (return a non-related type).
*Object.class
would; that is, that
* nothing is known about handled type.
*