General data-binding functionality for Jackson: works on core streaming API
—
Jackson's serialization framework provides a flexible and extensible system for converting Java objects to JSON. The framework is built around JsonSerializer implementations, SerializerProvider for context, and various factory and configuration classes that control the serialization process.
JsonSerializer is the abstract base class for all serializers that convert Java objects to JSON.
public abstract class JsonSerializer<T> {
// Core serialization method
public abstract void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException;
// Type-aware serialization (for polymorphic types)
public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException;
// Metadata methods
public Class<T> handledType();
public boolean isEmpty(SerializerProvider provider, T value);
public boolean isEmpty(T value);
public boolean usesObjectId();
// Contextual serialization
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException;
// Resolution support
public void resolve(SerializerProvider provider) throws JsonMappingException;
// Deprecated delegation
public JsonSerializer<T> replaceDelegatee(JsonSerializer<?> delegatee);
public JsonSerializer<?> getDelegatee();
// Schema support
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException;
// Iterator support for container types
public boolean isUnwrappingSerializer();
public JsonSerializer<T> unwrappingSerializer(NameTransformer unwrapper);
// Null handling marker classes
public static abstract class None extends JsonSerializer<Object> { }
}SerializerProvider provides context and factory functionality for serializers during the serialization process.
public abstract class SerializerProvider extends DatabindContext {
// Serializer lookup methods
public abstract JsonSerializer<Object> findValueSerializer(Class<?> valueType, BeanProperty property) throws JsonMappingException;
public abstract JsonSerializer<Object> findValueSerializer(JavaType valueType, BeanProperty property) throws JsonMappingException;
public abstract JsonSerializer<Object> findValueSerializer(Class<?> valueType) throws JsonMappingException;
public abstract JsonSerializer<Object> findValueSerializer(JavaType valueType) throws JsonMappingException;
// Primary value serializer (with type info)
public abstract JsonSerializer<Object> findPrimaryPropertySerializer(JavaType valueType, BeanProperty property) throws JsonMappingException;
public abstract JsonSerializer<Object> findPrimaryPropertySerializer(Class<?> valueType, BeanProperty property) throws JsonMappingException;
// Typed serializers
public abstract JsonSerializer<Object> findTypedValueSerializer(Class<?> valueType, boolean cache, BeanProperty property) throws JsonMappingException;
public abstract JsonSerializer<Object> findTypedValueSerializer(JavaType valueType, boolean cache, BeanProperty property) throws JsonMappingException;
// Key serializers
public abstract JsonSerializer<Object> findKeySerializer(JavaType keyType, BeanProperty property) throws JsonMappingException;
public abstract JsonSerializer<Object> findKeySerializer(Class<?> keyType, BeanProperty property) throws JsonMappingException;
// Content serializers
public abstract JsonSerializer<Object> findContentValueSerializer(Class<?> valueType, BeanProperty property) throws JsonMappingException;
public abstract JsonSerializer<Object> findContentValueSerializer(JavaType valueType, BeanProperty property) throws JsonMappingException;
// Null serializers
public abstract JsonSerializer<Object> getDefaultNullKeySerializer();
public abstract JsonSerializer<Object> getDefaultNullValueSerializer();
public abstract JsonSerializer<Object> findNullKeySerializer(JavaType serializationType, BeanProperty property) throws JsonMappingException;
public abstract JsonSerializer<Object> findNullValueSerializer(BeanProperty property) throws JsonMappingException;
// Unknown type serializer
public abstract JsonSerializer<Object> getUnknownTypeSerializer(Class<?> unknownType);
// Serialization methods
public void serializeValue(JsonGenerator gen, Object value) throws IOException;
public void serializeValue(JsonGenerator gen, Object value, JavaType rootType) throws IOException;
public void serializeValue(JsonGenerator gen, Object value, JavaType rootType, JsonSerializer<Object> ser) throws IOException;
public void defaultSerializeValue(JsonGenerator gen, Object value) throws IOException;
public void defaultSerializeField(String fieldName, Object value, JsonGenerator gen) throws IOException;
public void defaultSerializeNull(JsonGenerator gen) throws IOException;
// Polymorphic serialization
public void defaultSerializeValue(JsonGenerator gen, Object value, JavaType type) throws IOException;
// Exception handling
public void reportMappingProblem(String msg, Object... msgArgs) throws JsonMappingException;
public <T> T reportBadTypeDefinition(BeanDescription bean, String msg, Object... msgArgs) throws JsonMappingException;
public <T> T reportBadPropertyDefinition(BeanDescription bean, BeanPropertyDefinition prop, String message, Object... msgArgs) throws JsonMappingException;
// Configuration access
public abstract SerializationConfig getConfig();
// Filtering
public abstract FilterProvider getFilterProvider();
// View support
public final boolean isEnabled(MapperFeature feature);
public final boolean isEnabled(SerializationFeature feature);
public final boolean canOverrideAccessModifiers();
// Generator access
public JsonGenerator getGenerator();
// Attributes
public abstract Object getAttribute(Object key);
public abstract SerializerProvider setAttribute(Object key, Object value);
// Type factory access
public final TypeFactory getTypeFactory();
// Root name handling
public PropertyName findRootName(JavaType rootType);
public PropertyName findRootName(Class<?> rawRootType);
// Cached serializers
public abstract boolean hasSerializerFor(Class<?> cls, AtomicReference<Throwable> cause);
// Format-specific
public WritableObjectId findObjectId(Object forPojo, ObjectIdGenerator<?> generatorType);
// Date handling
public DateFormat getDateFormat();
public boolean hasDateFormat();
public Locale getLocale();
public TimeZone getTimeZone();
}Jackson provides standard serializers for common Java types.
public abstract class StdSerializer<T> extends JsonSerializer<T> implements JsonFormatVisitable, Serializable {
// Construction
protected StdSerializer(Class<T> t);
protected StdSerializer(JavaType type);
protected StdSerializer(Class<?> t, boolean dummy);
protected StdSerializer(StdSerializer<?> src);
// Type information
public Class<T> handledType();
// Schema support
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException;
public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException;
public JsonNode getSchema(SerializerProvider provider, Type typeHint, boolean isOptional) throws JsonMappingException;
// Utility methods for subclasses
protected void visitStringFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException;
protected void visitStringFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint, JsonValueFormat format) throws JsonMappingException;
protected void visitIntFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint, JsonParser.NumberType numberType) throws JsonMappingException;
protected void visitIntFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint, JsonParser.NumberType numberType, JsonValueFormat format) throws JsonMappingException;
protected void visitFloatFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException;
protected boolean isDefaultSerializer(JsonSerializer<?> serializer);
// Exception creation helpers
protected JsonMappingException wrapAndThrow(SerializerProvider provider, Throwable t, Object bean, String fieldName) throws JsonMappingException;
protected JsonMappingException wrapAndThrow(SerializerProvider provider, Throwable t, Object bean, int index) throws JsonMappingException;
}
// Scalar serializers
public abstract class StdScalarSerializer<T> extends StdSerializer<T> {
protected StdScalarSerializer(Class<T> t);
protected StdScalarSerializer(Class<?> t, boolean dummy);
public void serializeWithType(T value, JsonGenerator gen, SerializerProvider provider, TypeSerializer typeSer) throws IOException;
}public abstract class ContainerSerializer<T> extends StdSerializer<T> {
protected ContainerSerializer(Class<T> t);
protected ContainerSerializer(Class<?> t, boolean dummy);
protected ContainerSerializer(JavaType fullType);
protected ContainerSerializer(ContainerSerializer<?> src);
// Container-specific methods
public abstract boolean hasSingleElement(T value);
public abstract boolean isEmpty(SerializerProvider prov, T value);
// Content serializer access
protected abstract JsonSerializer<?> _withValueTypeSerializer(TypeSerializer vts);
}
// Array serializer
public class ObjectArraySerializer extends ArraySerializerBase<Object[]> {
public ObjectArraySerializer(JavaType elemType, boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> elementSerializer);
public JsonSerializer<?> _withValueTypeSerializer(TypeSerializer vts);
public ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts);
public void serializeContents(Object[] value, JsonGenerator gen, SerializerProvider provider) throws IOException;
public JsonNode getSchema(SerializerProvider provider, Type typeHint);
}
// Collection serializers
public class CollectionSerializer extends AsArraySerializerBase<Collection<?>> {
public CollectionSerializer(JavaType elemType, boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer);
public ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts);
public void serialize(Collection<?> value, JsonGenerator gen, SerializerProvider provider) throws IOException;
public void serializeContents(Collection<?> value, JsonGenerator gen, SerializerProvider provider) throws IOException;
}
// Map serializer
public class MapSerializer extends ContainerSerializer<Map<?, ?>> implements ContextualSerializer {
public MapSerializer(Set<String> ignoredEntries, JavaType keyType, JavaType valueType, boolean valueTypeIsStatic, TypeSerializer vts, JsonSerializer<?> keySerializer, JsonSerializer<?> valueSerializer);
public ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts);
public MapSerializer withResolved(BeanProperty property, JsonSerializer<?> keySerializer, JsonSerializer<?> valueSerializer, Set<String> ignored, boolean sortKeys);
public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException;
public void serialize(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider) throws IOException;
public void serializeOptionalFields(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider, Object suppressableValue) throws IOException;
public void serializeFields(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider) throws IOException;
public void serializeFieldsUsing(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException;
}public class BeanSerializer extends BeanSerializerBase implements Serializable {
// Construction
public BeanSerializer(JavaType type, BeanSerializerBuilder builder, BeanPropertyWriter[] properties, BeanPropertyWriter[] filteredProperties);
protected BeanSerializer(BeanSerializerBase src, ObjectIdWriter objectIdWriter);
protected BeanSerializer(BeanSerializerBase src, ObjectIdWriter objectIdWriter, Object filterId);
protected BeanSerializer(BeanSerializerBase src, Set<String> toIgnore, Set<String> toInclude);
// Factory methods
public static BeanSerializer createDummy(JavaType forType);
// Serialization
public void serialize(Object bean, JsonGenerator gen, SerializerProvider provider) throws IOException;
protected void serializeFields(Object bean, JsonGenerator gen, SerializerProvider provider) throws IOException;
protected void serializeFieldsFiltered(Object bean, JsonGenerator gen, SerializerProvider provider) throws IOException;
// String representation
public String toString();
}
public abstract class BeanSerializerBase extends StdSerializer<Object> implements ContextualSerializer, ResolvableSerializer, JsonFormatVisitable, Serializable {
// Property writers
protected final BeanPropertyWriter[] _props;
protected final BeanPropertyWriter[] _filteredProps;
// Special properties
protected final AnyGetterWriter _anyGetterWriter;
protected final Object _propertyFilterId;
protected final AnnotatedMember _typeIdDef;
// Object identity
protected final ObjectIdWriter _objectIdWriter;
// Shape and features
protected final JsonFormat.Shape _serializationShape;
// Construction
protected BeanSerializerBase(JavaType type, BeanSerializerBuilder builder, BeanPropertyWriter[] properties, BeanPropertyWriter[] filteredProperties);
protected BeanSerializerBase(BeanSerializerBase src, BeanPropertyWriter[] properties, BeanPropertyWriter[] filteredProperties);
protected BeanSerializerBase(BeanSerializerBase src, ObjectIdWriter objectIdWriter);
protected BeanSerializerBase(BeanSerializerBase src, ObjectIdWriter objectIdWriter, Object filterId);
protected BeanSerializerBase(BeanSerializerBase src, Set<String> toIgnore, Set<String> toInclude);
// Abstract serialization methods
public abstract void serialize(Object bean, JsonGenerator gen, SerializerProvider provider) throws IOException;
protected abstract void serializeFields(Object bean, JsonGenerator gen, SerializerProvider provider) throws IOException;
protected abstract void serializeFieldsFiltered(Object bean, JsonGenerator gen, SerializerProvider provider) throws IOException;
// Metadata
public boolean usesObjectId();
// Contextualization
public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException;
// Resolution
public void resolve(SerializerProvider provider) throws JsonMappingException;
// Schema support
public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException;
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException;
}public class BeanPropertyWriter extends PropertyWriter implements Serializable {
// Property metadata
protected final SerializedString _name;
protected final PropertyName _wrapperName;
protected final JavaType _declaredType;
protected final JavaType _cfgSerializationType;
protected final AnnotatedMember _member;
protected final BeanProperty.Std _internalSettings;
// Serialization
protected JsonSerializer<Object> _serializer;
protected JsonSerializer<Object> _nullSerializer;
protected TypeSerializer _typeSerializer;
// Filtering and inclusion
protected Class<?>[] _includeInViews;
protected PropertyFilter _filter;
protected Object _suppressableValue;
protected boolean _suppressNulls;
// Construction
public BeanPropertyWriter(BeanPropertyDefinition propDef, AnnotatedMember member, Annotations contextAnnotations, JavaType declaredType, JsonSerializer<?> ser, TypeSerializer typeSer, JavaType serType, boolean suppressNulls, Object suppressableValue, Class<?>[] includeInViews);
protected BeanPropertyWriter(BeanPropertyWriter base, PropertyName name);
protected BeanPropertyWriter(BeanPropertyWriter base, JsonSerializer<?> ser);
// Factory methods
public BeanPropertyWriter rename(PropertyName newName);
public BeanPropertyWriter withSerializer(JsonSerializer<?> ser);
public BeanPropertyWriter withNullSerializer(JsonSerializer<?> nullSer);
// Assignment
public void assignSerializer(JsonSerializer<Object> ser);
public void assignNullSerializer(JsonSerializer<Object> nullSer);
public void assignTypeSerializer(TypeSerializer typeSer);
// Serialization
public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception;
public void serializeAsOmittedField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception;
public void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception;
public void serializeAsPlaceholder(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception;
// Value access
public Object get(Object bean) throws Exception;
public void set(Object bean, Object value) throws Exception;
// Property information
public String getName();
public PropertyName getFullName();
public JavaType getType();
public PropertyName getWrapperName();
public AnnotatedMember getMember();
public <A extends Annotation> A getAnnotation(Class<A> acls);
public <A extends Annotation> A getContextAnnotation(Class<A> acls);
// Filtering and views
public boolean willSuppressNulls();
public Class<?>[] getViews();
// Schema support
public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor, SerializerProvider provider) throws JsonMappingException;
// String representation
public String toString();
}public abstract class SerializerFactory {
// Serializer creation
public abstract JsonSerializer<Object> createSerializer(SerializerProvider prov, JavaType type) throws JsonMappingException;
public abstract JsonSerializer<Object> createKeySerializer(SerializerProvider prov, JavaType type, JsonSerializer<Object> defaultImpl) throws JsonMappingException;
// Type serializer creation
public abstract TypeSerializer createTypeSerializer(SerializationConfig config, JavaType baseType) throws JsonMappingException;
// Configuration
public abstract SerializerFactory withAdditionalSerializers(Serializers additional);
public abstract SerializerFactory withAdditionalKeySerializers(Serializers additional);
public abstract SerializerFactory withSerializerModifier(BeanSerializerModifier modifier);
public abstract SerializerFactory withConfig(SerializationConfig config);
}
public class BeanSerializerFactory extends BasicSerializerFactory implements Serializable {
// Singleton instance
public static final BeanSerializerFactory instance;
// Construction
public BeanSerializerFactory(SerializerFactoryConfig config);
// Factory methods
public SerializerFactory withConfig(SerializationConfig config);
public SerializerFactory withAdditionalSerializers(Serializers additional);
public SerializerFactory withAdditionalKeySerializers(Serializers additional);
public SerializerFactory withSerializerModifier(BeanSerializerModifier modifier);
// Serializer creation
public JsonSerializer<Object> createSerializer(SerializerProvider prov, JavaType type) throws JsonMappingException;
// Bean serializer creation
public JsonSerializer<Object> findBeanSerializer(SerializerProvider prov, JavaType type, BeanDescription beanDesc) throws JsonMappingException;
public JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov, BeanDescription beanDesc) throws JsonMappingException;
// Builder creation
protected BeanSerializerBuilder constructBeanSerializerBuilder(BeanDescription beanDesc);
protected BeanSerializer createBeanSerializer(SerializerProvider prov, JavaType type, BeanDescription beanDesc, JsonFormat.Value format) throws JsonMappingException;
// Property handling
protected void removeIgnorableTypes(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyDefinition> properties);
protected void removeSetterlessGetters(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyDefinition> properties);
protected void addBeanProps(SerializationConfig config, BeanDescription beanDesc, BeanSerializerBuilder builder) throws JsonMappingException;
protected List<BeanPropertyWriter> findBeanProperties(SerializerProvider prov, BeanDescription beanDesc, BeanSerializerBuilder builder) throws JsonMappingException;
protected BeanPropertyWriter buildWriter(SerializerProvider prov, BeanPropertyDefinition propDef, JavaType declaredType, JsonSerializer<?> ser, TypeSerializer typeSer, TypeSerializer contentTypeSer, AnnotatedMember am, boolean defaultUseStaticTyping) throws JsonMappingException;
// Filtering
protected PropertyFilter findPropertyFilter(SerializerProvider provider, Object filterId, Object valueToFilter) throws JsonMappingException;
}public final class SerializationConfig extends MapperConfigBase<SerializationFeature, SerializationConfig> implements Serializable {
// Construction
public SerializationConfig(BaseSettings base, SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, ConfigOverrides configOverrides);
// Configuration modification
public SerializationConfig with(SerializationFeature feature);
public SerializationConfig with(SerializationFeature first, SerializationFeature... features);
public SerializationConfig withFeatures(SerializationFeature... features);
public SerializationConfig without(SerializationFeature feature);
public SerializationConfig without(SerializationFeature first, SerializationFeature... features);
public SerializationConfig withoutFeatures(SerializationFeature... features);
// Feature checking
public boolean isEnabled(SerializationFeature f);
public int getSerializationFeatures();
// Generator configuration
public SerializationConfig with(JsonGenerator.Feature feature);
public SerializationConfig withFeatures(JsonGenerator.Feature... features);
public SerializationConfig without(JsonGenerator.Feature feature);
public SerializationConfig withoutFeatures(JsonGenerator.Feature... features);
// Other configuration
public SerializationConfig with(FilterProvider filters);
public SerializationConfig withDefaultPrettyPrinter(PrettyPrinter pp);
public SerializationConfig withRootName(PropertyName rootName);
public SerializationConfig withRootName(String rootName);
public SerializationConfig withView(Class<?> view);
// Access methods
public FilterProvider getFilterProvider();
public PrettyPrinter getDefaultPrettyPrinter();
public <T extends BeanDescription> T introspect(JavaType type);
// Serialization inclusion
public JsonInclude.Value getDefaultPropertyInclusion();
public JsonInclude.Value getDefaultPropertyInclusion(Class<?> baseType);
public JsonInclude.Value getDefaultInclusion(Class<?> baseType, Class<?> propertyType);
// Date format
public String getDateFormatPattern();
public DateFormat getDateFormat();
// Root name handling
public PropertyName findRootName(JavaType rootType);
public PropertyName findRootName(Class<?> rawRootType);
// View support
public Class<?> getActiveView();
// Attributes
public ContextAttributes getAttributes();
}public enum SerializationFeature implements ConfigFeature {
// Wrapping and formatting
WRAP_ROOT_VALUE(false),
INDENT_OUTPUT(false),
// Error handling
FAIL_ON_EMPTY_BEANS(true),
FAIL_ON_SELF_REFERENCES(true),
WRAP_EXCEPTIONS(true),
FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS(true),
// Reference handling
WRITE_SELF_REFERENCES_AS_NULL(false),
// Resource management
CLOSE_CLOSEABLE(false),
FLUSH_AFTER_WRITE_VALUE(true),
// Date and time handling
WRITE_DATES_AS_TIMESTAMPS(true),
WRITE_DATE_KEYS_AS_TIMESTAMPS(false),
WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS(true),
// Array and character handling
WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS(false),
// Enum handling
WRITE_ENUMS_USING_TO_STRING(false),
WRITE_ENUMS_USING_INDEX(false),
WRITE_ENUM_KEYS_USING_INDEX(false),
// Map handling
WRITE_NULL_MAP_VALUES(true),
WRITE_EMPTY_JSON_ARRAYS(true),
WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED(false),
ORDER_MAP_ENTRIES_BY_KEYS(false),
// Number handling
WRITE_BIGDECIMAL_AS_PLAIN(false),
// Object identity
USE_EQUALITY_FOR_OBJECT_ID(false);
private final boolean _defaultState;
private final int _mask;
private SerializationFeature(boolean defaultState) {
_defaultState = defaultState;
_mask = (1 << ordinal());
}
public boolean enabledByDefault() {
return _defaultState;
}
public int getMask() {
return _mask;
}
public boolean enabledIn(int flags) {
return (flags & _mask) != 0;
}
}import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
// Custom serializer for Person class
public class PersonSerializer extends StdSerializer<Person> {
public PersonSerializer() {
this(null);
}
public PersonSerializer(Class<Person> t) {
super(t);
}
@Override
public void serialize(Person person, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("fullName", person.getFirstName() + " " + person.getLastName());
gen.writeNumberField("age", person.getAge());
// Custom date formatting
if (person.getBirthDate() != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
gen.writeStringField("birthDate", sdf.format(person.getBirthDate()));
}
// Conditional field
if (person.isActive()) {
gen.writeStringField("status", "ACTIVE");
}
gen.writeEndObject();
}
// Optional: provide schema information
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
JsonObjectFormatVisitor objectVisitor = visitor.expectObjectFormat(typeHint);
if (objectVisitor != null) {
objectVisitor.property("fullName", JsonFormatTypes.STRING);
objectVisitor.property("age", JsonFormatTypes.INTEGER);
objectVisitor.optionalProperty("birthDate", JsonFormatTypes.STRING);
objectVisitor.optionalProperty("status", JsonFormatTypes.STRING);
}
}
}
// Register with ObjectMapper
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(Person.class, new PersonSerializer());
mapper.registerModule(module);
// Use
Person person = new Person("John", "Doe", 30);
String json = mapper.writeValueAsString(person);
// Result: {"fullName":"John Doe","age":30,"status":"ACTIVE"}// Contextual serializer that adapts based on property annotations
public class MoneySerializer extends StdSerializer<Money> implements ContextualSerializer {
private final String currency;
private final boolean showSymbol;
public MoneySerializer() {
this(null, false);
}
private MoneySerializer(String currency, boolean showSymbol) {
super(Money.class);
this.currency = currency;
this.showSymbol = showSymbol;
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
if (property != null) {
CurrencyFormat ann = property.getAnnotation(CurrencyFormat.class);
if (ann != null) {
return new MoneySerializer(ann.currency(), ann.showSymbol());
}
}
return this;
}
@Override
public void serialize(Money money, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (showSymbol) {
String symbol = getCurrencySymbol(currency != null ? currency : money.getCurrency());
gen.writeString(symbol + money.getAmount());
} else {
gen.writeNumber(money.getAmount());
}
}
private String getCurrencySymbol(String currency) {
return switch (currency) {
case "USD" -> "$";
case "EUR" -> "€";
case "GBP" -> "£";
default -> currency + " ";
};
}
}
// Custom annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CurrencyFormat {
String currency() default "";
boolean showSymbol() default false;
}
// Usage in POJO
public class Product {
private String name;
@CurrencyFormat(currency = "USD", showSymbol = true)
private Money price;
@CurrencyFormat(currency = "USD", showSymbol = false)
private Money cost;
// getters/setters
}// Custom collection serializer
public class PagedResultSerializer extends ContainerSerializer<PagedResult<?>> {
private final JavaType elementType;
private final JsonSerializer<Object> elementSerializer;
public PagedResultSerializer(JavaType elementType, JsonSerializer<Object> elementSerializer) {
super(PagedResult.class);
this.elementType = elementType;
this.elementSerializer = elementSerializer;
}
@Override
public void serialize(PagedResult<?> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
gen.writeArrayFieldStart("items");
for (Object item : value.getItems()) {
if (elementSerializer != null) {
elementSerializer.serialize(item, gen, serializers);
} else {
serializers.defaultSerializeValue(item, gen);
}
}
gen.writeEndArray();
gen.writeNumberField("totalCount", value.getTotalCount());
gen.writeNumberField("pageNumber", value.getPageNumber());
gen.writeNumberField("pageSize", value.getPageSize());
gen.writeBooleanField("hasNext", value.isHasNext());
gen.writeEndObject();
}
@Override
public boolean hasSingleElement(PagedResult<?> value) {
return value.getItems().size() == 1;
}
@Override
public boolean isEmpty(SerializerProvider prov, PagedResult<?> value) {
return value.getItems().isEmpty();
}
@Override
protected JsonSerializer<?> _withValueTypeSerializer(TypeSerializer vts) {
// Return new instance with type serializer if needed
return this;
}
}// Custom property writer for computed fields
public class ComputedPropertyWriter extends BeanPropertyWriter {
private final Function<Object, Object> computer;
public ComputedPropertyWriter(BeanPropertyDefinition propDef, AnnotatedMember member,
Function<Object, Object> computer) {
super(propDef, member, null, propDef.getPrimaryType(), null, null,
propDef.getPrimaryType(), false, null, null);
this.computer = computer;
}
@Override
public Object get(Object bean) throws Exception {
// Compute value dynamically
return computer.apply(bean);
}
@Override
public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {
Object value = get(bean);
if (value == null) {
if (_nullSerializer != null) {
gen.writeFieldName(_name);
_nullSerializer.serialize(null, gen, prov);
}
} else {
gen.writeFieldName(_name);
if (_serializer == null) {
prov.defaultSerializeValue(value, gen);
} else {
_serializer.serialize(value, gen, prov);
}
}
}
}
// Usage in custom bean serializer modifier
public class ComputedFieldSerializerModifier extends BeanSerializerModifier {
@Override
public BeanSerializerBuilder updateBuilder(SerializationConfig config, BeanDescription beanDesc, BeanSerializerBuilder builder) {
// Add computed properties
if (beanDesc.getBeanClass() == Person.class) {
// Add fullName computed field
SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(
config, null, new PropertyName("fullName"), PropertyMetadata.STD_REQUIRED_OR_OPTIONAL);
ComputedPropertyWriter writer = new ComputedPropertyWriter(propDef, null,
bean -> {
Person person = (Person) bean;
return person.getFirstName() + " " + person.getLastName();
});
builder.addProperty(writer);
}
return builder;
}
}// Custom property filter
public class DynamicPropertyFilter implements PropertyFilter {
private final Set<String> allowedFields;
private final Predicate<Object> condition;
public DynamicPropertyFilter(Set<String> allowedFields, Predicate<Object> condition) {
this.allowedFields = allowedFields;
this.condition = condition;
}
@Override
public void serializeAsField(Object pojo, JsonGenerator gen, SerializerProvider prov, PropertyWriter writer) throws Exception {
if (include(writer.getName(), pojo)) {
writer.serializeAsField(pojo, gen, prov);
} else {
writer.serializeAsOmittedField(pojo, gen, prov);
}
}
@Override
public void serializeAsElement(Object elementValue, JsonGenerator gen, SerializerProvider prov, PropertyWriter writer) throws Exception {
writer.serializeAsElement(elementValue, gen, prov);
}
@Override
public void depositSchemaProperty(PropertyWriter writer, ObjectNode propertiesNode, SerializerProvider provider) throws JsonMappingException {
writer.depositSchemaProperty(propertiesNode, provider);
}
private boolean include(String fieldName, Object pojo) {
return allowedFields.contains(fieldName) && condition.test(pojo);
}
}
// Usage with FilterProvider
SimpleFilterProvider filterProvider = new SimpleFilterProvider();
filterProvider.addFilter("dynamicFilter", new DynamicPropertyFilter(
Set.of("name", "age", "email"),
obj -> ((Person) obj).isActive()
));
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
// POJO with filter annotation
@JsonFilter("dynamicFilter")
public class Person {
// fields and methods
}ObjectMapper mapper = new ObjectMapper();
// Configure serialization features
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
// Multiple features at once
mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,
SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
mapper.disable(SerializationFeature.WRITE_NULL_MAP_VALUES,
SerializationFeature.WRITE_EMPTY_JSON_ARRAYS);
// Check feature status
boolean indented = mapper.isEnabled(SerializationFeature.INDENT_OUTPUT);
boolean timestampsAsNumbers = mapper.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// Configure through ObjectWriter
ObjectWriter writer = mapper.writer()
.with(SerializationFeature.INDENT_OUTPUT)
.without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.withDefaultPrettyPrinter();
String json = writer.writeValueAsString(object);// Serializer interfaces
public interface ContextualSerializer {
JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException;
}
public interface ResolvableSerializer {
void resolve(SerializerProvider provider) throws JsonMappingException;
}
// Property writer base
public abstract class PropertyWriter implements BeanProperty {
public abstract void serializeAsField(Object value, JsonGenerator gen, SerializerProvider prov) throws Exception;
public abstract void serializeAsOmittedField(Object value, JsonGenerator gen, SerializerProvider prov) throws Exception;
public abstract void serializeAsElement(Object value, JsonGenerator gen, SerializerProvider prov) throws Exception;
public void serializeAsPlaceholder(Object value, JsonGenerator gen, SerializerProvider prov) throws Exception;
public abstract void depositSchemaProperty(JsonObjectFormatVisitor v, SerializerProvider provider) throws JsonMappingException;
}
// Serializer cache
public final class SerializerCache {
public int cachedSerializersCount();
public void flushCachedSerializers();
public JsonSerializer<Object> untypedValueSerializer(Class<?> type);
public JsonSerializer<Object> untypedValueSerializer(JavaType type);
public ReadOnlyClassToSerializerMap getReadOnlyLookupMap();
}
// Serializer registration interface
public interface Serializers {
JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc);
JsonSerializer<?> findReferenceSerializer(SerializationConfig config, ReferenceType type, BeanDescription beanDesc, TypeSerializer contentTypeSerializer, JsonSerializer<Object> contentValueSerializer);
JsonSerializer<?> findArraySerializer(SerializationConfig config, ArrayType type, BeanDescription beanDesc, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer);
JsonSerializer<?> findCollectionSerializer(SerializationConfig config, CollectionType type, BeanDescription beanDesc, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer);
JsonSerializer<?> findCollectionLikeSerializer(SerializationConfig config, CollectionLikeType type, BeanDescription beanDesc, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer);
JsonSerializer<?> findMapSerializer(SerializationConfig config, MapType type, BeanDescription beanDesc, JsonSerializer<Object> keySerializer, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer);
JsonSerializer<?> findMapLikeSerializer(SerializationConfig config, MapLikeType type, BeanDescription beanDesc, JsonSerializer<Object> keySerializer, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer);
public abstract static class Base implements Serializers {
// Default implementations returning null
}
}
// Bean serializer modifier
public abstract class BeanSerializerModifier {
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties);
public List<BeanPropertyWriter> orderProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties);
public BeanSerializerBuilder updateBuilder(SerializationConfig config, BeanDescription beanDesc, BeanSerializerBuilder builder);
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer);
public JsonSerializer<?> modifyArraySerializer(SerializationConfig config, ArrayType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer);
public JsonSerializer<?> modifyCollectionSerializer(SerializationConfig config, CollectionType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer);
public JsonSerializer<?> modifyCollectionLikeSerializer(SerializationConfig config, CollectionLikeType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer);
public JsonSerializer<?> modifyMapSerializer(SerializationConfig config, MapType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer);
public JsonSerializer<?> modifyMapLikeSerializer(SerializationConfig config, MapLikeType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer);
public JsonSerializer<?> modifyEnumSerializer(SerializationConfig config, JavaType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer);
public JsonSerializer<?> modifyKeySerializer(SerializationConfig config, JavaType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer);
}Install with Tessl CLI
npx tessl i tessl/maven-com-fasterxml-jackson-core--jackson-databind