General data-binding functionality for Jackson: works on core streaming API
—
Jackson's module system provides a clean and extensible way to add functionality to ObjectMapper without modifying core classes. Modules can register custom serializers, deserializers, type resolvers, naming strategies, and other components. This system enables both Jackson's own extensions and third-party libraries to integrate seamlessly.
Module is the abstract base class for all Jackson modules.
public abstract class Module implements Versioned {
// Module identification
public abstract String getModuleName();
public abstract Version version();
// Module setup - called when module is registered
public abstract void setupModule(SetupContext context);
// Optional setup methods
public Object getTypeId();
public Iterable<? extends Deserializer> getDeserializers();
public Iterable<? extends Serializer> getSerializers();
public Iterable<? extends BeanDeserializerModifier> getBeanDeserializerModifiers();
public Iterable<? extends BeanSerializerModifier> getBeanSerializerModifiers();
// Setup context interface
public static interface SetupContext {
// Version information
Version getMapperVersion();
// Configuration access
MapperConfig<?> getConfig();
DeserializationConfig getDeserializationConfig();
SerializationConfig getSerializationConfig();
TypeFactory getTypeFactory();
// Component registration
void addDeserializers(Deserializers d);
void addKeyDeserializers(KeyDeserializers d);
void addSerializers(Serializers s);
void addKeySerializers(Serializers s);
void addBeanDeserializerModifier(BeanDeserializerModifier mod);
void addBeanSerializerModifier(BeanSerializerModifier mod);
void addAbstractTypeResolver(AbstractTypeResolver resolver);
void addTypeModifier(TypeModifier modifier);
void addValueInstantiators(ValueInstantiators instantiators);
// Configuration modification
void setClassIntrospector(ClassIntrospector ci);
void insertAnnotationIntrospector(AnnotationIntrospector ai);
void appendAnnotationIntrospector(AnnotationIntrospector ai);
void registerSubtypes(Class<?>... subtypes);
void registerSubtypes(NamedType... subtypes);
void registerSubtypes(Collection<Class<?>> subtypes);
void setMixInAnnotations(Class<?> target, Class<?> mixinSource);
void addDeserializationProblemHandler(DeserializationProblemHandler handler);
void setNamingStrategy(PropertyNamingStrategy naming);
// Deprecated methods (for compatibility)
@Deprecated
void addBeanSerializerModifier(BeanSerializerModifier modifier);
@Deprecated
void addBeanDeserializerModifier(BeanDeserializerModifier modifier);
}
}SimpleModule provides a convenient base implementation for creating custom modules.
public class SimpleModule extends Module implements Serializable {
// Construction
public SimpleModule();
public SimpleModule(String name);
public SimpleModule(String name, Version version);
public SimpleModule(String name, Version version, Map<Class<?>, JsonDeserializer<?>> deserializers);
public SimpleModule(String name, Version version, List<JsonSerializer<?>> serializers);
public SimpleModule(String name, Version version, Map<Class<?>, JsonDeserializer<?>> deserializers, List<JsonSerializer<?>> serializers);
// Module identification
public String getModuleName();
public Version version();
public Object getTypeId();
// Setup
public void setupModule(SetupContext context);
// Serializer registration
public SimpleModule addSerializer(JsonSerializer<?> ser);
public <T> SimpleModule addSerializer(Class<? extends T> type, JsonSerializer<T> ser);
public SimpleModule addKeySerializer(Class<?> type, JsonSerializer<?> ser);
// Deserializer registration
public SimpleModule addDeserializer(Class<?> type, JsonDeserializer<?> deser);
public SimpleModule addKeyDeserializer(Class<?> type, KeyDeserializer deser);
// Abstract type resolution
public SimpleModule addAbstractTypeMapping(Class<?> superType, Class<?> subType);
public SimpleModule addAbstractTypeResolver(AbstractTypeResolver resolver);
// Type modification
public SimpleModule addTypeModifier(TypeModifier modifier);
// Value instantiation
public SimpleModule addValueInstantiator(Class<?> beanType, ValueInstantiator inst);
// Mix-in annotations
public SimpleModule setMixInAnnotation(Class<?> targetType, Class<?> mixinClass);
// Naming strategy
public SimpleModule setNamingStrategy(PropertyNamingStrategy naming);
// Modifier registration
public SimpleModule setDeserializerModifier(BeanDeserializerModifier mod);
public SimpleModule setSerializerModifier(BeanSerializerModifier mod);
// Subtype registration
public SimpleModule registerSubtypes(Class<?>... subtypes);
public SimpleModule registerSubtypes(NamedType... subtypes);
public SimpleModule registerSubtypes(Collection<Class<?>> subtypes);
// Introspector modification
public SimpleModule setClassIntrospector(ClassIntrospector ci);
public SimpleModule insertAnnotationIntrospector(AnnotationIntrospector ai);
public SimpleModule appendAnnotationIntrospector(AnnotationIntrospector ai);
// Problem handler registration
public SimpleModule addDeserializationProblemHandler(DeserializationProblemHandler handler);
}Interface for registering custom serializers.
public interface Serializers {
// Serializer lookup methods
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);
// Base implementation
public static abstract class Base implements Serializers {
// Default implementations returning null
}
}
// Utility classes
public class SimpleSerializers extends Serializers.Base {
// Map-based serializer storage
public SimpleSerializers();
public SimpleSerializers(Map<Class<?>, JsonSerializer<?>> serializers);
// Registration methods
public SimpleSerializers addSerializer(JsonSerializer<?> ser);
public <T> SimpleSerializers addSerializer(Class<? extends T> type, JsonSerializer<T> ser);
public void addSerializers(Map<Class<?>, JsonSerializer<?>> serializers);
// Lookup implementation
public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc);
}Interface for registering custom deserializers.
public interface Deserializers {
// Deserializer lookup methods
JsonDeserializer<?> findBeanDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException;
JsonDeserializer<?> findReferenceDeserializer(ReferenceType refType, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer contentTypeDeserializer, JsonDeserializer<?> contentDeserializer) throws JsonMappingException;
JsonDeserializer<?> findArrayDeserializer(ArrayType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException;
JsonDeserializer<?> findCollectionDeserializer(CollectionType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException;
JsonDeserializer<?> findCollectionLikeDeserializer(CollectionLikeType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException;
JsonDeserializer<?> findMapDeserializer(MapType type, DeserializationConfig config, BeanDescription beanDesc, KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException;
JsonDeserializer<?> findMapLikeDeserializer(MapLikeType type, DeserializationConfig config, BeanDescription beanDesc, KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException;
JsonDeserializer<?> findEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException;
JsonDeserializer<?> findTreeNodeDeserializer(Class<? extends JsonNode> nodeType, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException;
// Base implementation
public static abstract class Base implements Deserializers {
// Default implementations returning null
}
}
// Utility classes
public class SimpleDeserializers extends Deserializers.Base {
// Map-based deserializer storage
public SimpleDeserializers();
public SimpleDeserializers(Map<Class<?>, JsonDeserializer<?>> deserializers);
// Registration methods
public SimpleDeserializers addDeserializer(Class<?> type, JsonDeserializer<?> deser);
public void addDeserializers(Map<Class<?>, JsonDeserializer<?>> deserializers);
// Lookup implementation
public JsonDeserializer<?> findBeanDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc);
public JsonDeserializer<?> findEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription beanDesc);
public JsonDeserializer<?> findTreeNodeDeserializer(Class<? extends JsonNode> nodeType, DeserializationConfig config, BeanDescription beanDesc);
}Interface for registering custom key deserializers for maps.
public interface KeyDeserializers {
// Key deserializer lookup
KeyDeserializer findKeyDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException;
}
public class SimpleKeyDeserializers implements KeyDeserializers, Serializable {
// Map-based key deserializer storage
public SimpleKeyDeserializers();
// Registration
public SimpleKeyDeserializers addDeserializer(Class<?> type, KeyDeserializer deser);
// Lookup implementation
public KeyDeserializer findKeyDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc);
}Interface for registering custom value instantiators.
public interface ValueInstantiators {
// Value instantiator lookup
ValueInstantiator findValueInstantiator(DeserializationConfig config, BeanDescription beanDesc, ValueInstantiator defaultInstantiator);
}
public class SimpleValueInstantiators implements ValueInstantiators, Serializable {
// Map-based instantiator storage
public SimpleValueInstantiators();
// Registration
public SimpleValueInstantiators addValueInstantiator(Class<?> type, ValueInstantiator inst);
// Lookup implementation
public ValueInstantiator findValueInstantiator(DeserializationConfig config, BeanDescription beanDesc, ValueInstantiator defaultInstantiator);
}Interface for resolving abstract types to concrete implementations.
public abstract class AbstractTypeResolver {
// Type resolution
public abstract JavaType findTypeMapping(DeserializationConfig config, JavaType type) throws JsonMappingException;
public abstract JavaType resolveAbstractType(DeserializationConfig config, BeanDescription typeDesc) throws JsonMappingException;
}
public class SimpleAbstractTypeResolver extends AbstractTypeResolver {
// Map-based type mapping storage
public SimpleAbstractTypeResolver();
// Mapping registration
public <T> SimpleAbstractTypeResolver addMapping(Class<T> superType, Class<? extends T> subType);
// Resolution implementation
public JavaType findTypeMapping(DeserializationConfig config, JavaType type);
public JavaType resolveAbstractType(DeserializationConfig config, BeanDescription typeDesc);
}import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.module.SimpleModule;
// Create a simple module for custom types
public class CustomTypesModule extends SimpleModule {
public CustomTypesModule() {
super("CustomTypesModule", Version.unknownVersion());
// Add custom serializers
addSerializer(Money.class, new MoneySerializer());
addSerializer(PhoneNumber.class, new PhoneNumberSerializer());
// Add custom deserializers
addDeserializer(Money.class, new MoneyDeserializer());
addDeserializer(PhoneNumber.class, new PhoneNumberDeserializer());
// Add key deserializers
addKeyDeserializer(Money.class, new MoneyKeyDeserializer());
// Abstract type mappings
addAbstractTypeMapping(Payment.class, CreditCardPayment.class);
}
}
// Money serializer
public class MoneySerializer extends StdSerializer<Money> {
public MoneySerializer() {
super(Money.class);
}
@Override
public void serialize(Money money, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("currency", money.getCurrency());
gen.writeNumberField("amount", money.getAmount());
gen.writeEndObject();
}
}
// Money deserializer
public class MoneyDeserializer extends StdDeserializer<Money> {
public MoneyDeserializer() {
super(Money.class);
}
@Override
public Money deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonNode node = p.getCodec().readTree(p);
String currency = node.get("currency").asText();
BigDecimal amount = new BigDecimal(node.get("amount").asText());
return new Money(currency, amount);
}
}
// Usage
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new CustomTypesModule());
Money money = new Money("USD", new BigDecimal("99.99"));
String json = mapper.writeValueAsString(money);
Money parsed = mapper.readValue(json, Money.class);public class EnhancedValidationModule extends SimpleModule {
public EnhancedValidationModule() {
super("EnhancedValidationModule", new Version(1, 0, 0, null, "com.example", "validation"));
// Bean deserializer modifier for validation
setDeserializerModifier(new ValidationBeanDeserializerModifier());
// Custom annotation introspector
insertAnnotationIntrospector(new ValidationAnnotationIntrospector());
// Problem handler for validation errors
addDeserializationProblemHandler(new ValidationProblemHandler());
// Custom value instantiator for validated objects
addValueInstantiator(ValidatedObject.class, new ValidatedObjectInstantiator());
}
// Custom bean deserializer modifier that adds validation
private static class ValidationBeanDeserializerModifier extends BeanDeserializerModifier {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
// Wrap deserializer with validation if class has validation annotations
if (hasValidationAnnotations(beanDesc.getBeanClass())) {
return new ValidatingDeserializer(deserializer);
}
return deserializer;
}
private boolean hasValidationAnnotations(Class<?> beanClass) {
// Check for validation annotations
return beanClass.isAnnotationPresent(Validated.class) ||
Arrays.stream(beanClass.getDeclaredFields())
.anyMatch(field -> field.isAnnotationPresent(NotNull.class) ||
field.isAnnotationPresent(NotEmpty.class));
}
}
// Validating deserializer wrapper
private static class ValidatingDeserializer extends DelegatingDeserializer {
protected ValidatingDeserializer(JsonDeserializer<?> delegatee) {
super(delegatee);
}
@Override
protected JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDelegatee) {
return new ValidatingDeserializer(newDelegatee);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
Object result = _delegatee.deserialize(p, ctxt);
// Perform validation
List<String> errors = validateObject(result);
if (!errors.isEmpty()) {
throw new JsonMappingException(p, "Validation failed: " + String.join(", ", errors));
}
return result;
}
private List<String> validateObject(Object obj) {
List<String> errors = new ArrayList<>();
Class<?> clazz = obj.getClass();
// Simple validation logic
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
try {
Object value = field.get(obj);
if (field.isAnnotationPresent(NotNull.class) && value == null) {
errors.add(field.getName() + " cannot be null");
}
if (field.isAnnotationPresent(NotEmpty.class)) {
if (value == null ||
(value instanceof String && ((String) value).isEmpty()) ||
(value instanceof Collection && ((Collection<?>) value).isEmpty())) {
errors.add(field.getName() + " cannot be empty");
}
}
} catch (IllegalAccessException e) {
// Handle reflection errors
}
}
return errors;
}
}
}
// Custom annotations for validation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Validated {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotNull {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotEmpty {
}
// Usage
@Validated
public class User {
@NotNull
private String username;
@NotEmpty
private String email;
private String displayName; // Optional
// constructors, getters, setters
}
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new EnhancedValidationModule());
// This will throw validation error for missing required fields
String invalidJson = "{\"displayName\":\"John\"}";
try {
User user = mapper.readValue(invalidJson, User.class);
} catch (JsonMappingException e) {
System.out.println("Validation failed: " + e.getMessage());
}public class ConditionalModule extends SimpleModule {
public ConditionalModule() {
super("ConditionalModule");
}
@Override
public void setupModule(SetupContext context) {
DeserializationConfig deserConfig = context.getDeserializationConfig();
SerializationConfig serConfig = context.getSerializationConfig();
// Only add certain serializers based on configuration
if (serConfig.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
context.addSerializers(new PrettySerializers());
}
// Add different deserializers based on features
if (deserConfig.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
context.addDeserializers(new StrictDeserializers());
} else {
context.addDeserializers(new LenientDeserializers());
}
// Version-based conditional registration
Version mapperVersion = context.getMapperVersion();
if (mapperVersion.getMajorVersion() >= 2 && mapperVersion.getMinorVersion() >= 15) {
context.addTypeModifier(new NewTypeModifier());
}
}
private static class PrettySerializers extends Serializers.Base {
@Override
public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) {
if (type.getRawClass() == ComplexObject.class) {
return new PrettyComplexObjectSerializer();
}
return null;
}
}
}// Create a module finder utility
public class ModuleDiscovery {
public static List<Module> findModules() {
List<Module> modules = new ArrayList<>();
// Look for modules in classpath
ServiceLoader<Module> loader = ServiceLoader.load(Module.class);
for (Module module : loader) {
modules.add(module);
}
// Add specific known modules
if (isClassAvailable("java.time.LocalDate")) {
modules.add(new JavaTimeModule());
}
if (isClassAvailable("org.joda.time.DateTime")) {
modules.add(new JodaModule());
}
return modules;
}
private static boolean isClassAvailable(String className) {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
public static ObjectMapper createConfiguredMapper() {
ObjectMapper mapper = new ObjectMapper();
// Auto-register discovered modules
List<Module> modules = findModules();
mapper.registerModules(modules);
return mapper;
}
}
// Usage
ObjectMapper mapper = ModuleDiscovery.createConfiguredMapper();// Module that adds support for multiple formats
public class MultiFormatModule extends SimpleModule {
public MultiFormatModule() {
super("MultiFormatModule");
// Date format support
addSerializer(Date.class, new FlexibleDateSerializer());
addDeserializer(Date.class, new FlexibleDateDeserializer());
// Number format support
addSerializer(BigDecimal.class, new ContextualBigDecimalSerializer());
addDeserializer(BigDecimal.class, new ContextualBigDecimalDeserializer());
}
// Date serializer that adapts to context
private static class FlexibleDateSerializer extends StdSerializer<Date> implements ContextualSerializer {
private final DateFormat dateFormat;
public FlexibleDateSerializer() {
this(null);
}
private FlexibleDateSerializer(DateFormat dateFormat) {
super(Date.class);
this.dateFormat = dateFormat;
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
if (property != null) {
JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat(property.getMember());
if (format != null && format.hasPattern()) {
return new FlexibleDateSerializer(new SimpleDateFormat(format.getPattern()));
}
}
return this;
}
@Override
public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (dateFormat != null) {
gen.writeString(dateFormat.format(value));
} else {
// Use timestamp or default format based on configuration
if (serializers.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)) {
gen.writeNumber(value.getTime());
} else {
gen.writeString(value.toString());
}
}
}
}
}// Utility class for testing modules
public class ModuleTestUtils {
public static void testModuleRegistration(Module module) {
ObjectMapper mapper = new ObjectMapper();
// Test module registration
mapper.registerModule(module);
// Verify module is registered
Set<Object> moduleIds = mapper.getRegisteredModuleIds();
boolean found = moduleIds.stream()
.anyMatch(id -> id.equals(module.getTypeId()) ||
id.toString().contains(module.getModuleName()));
if (!found) {
throw new IllegalStateException("Module not properly registered: " + module.getModuleName());
}
System.out.println("Module registered successfully: " + module.getModuleName());
}
public static void testSerializationRoundTrip(Module module, Object testObject, Class<?> type) {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
try {
// Serialize
String json = mapper.writeValueAsString(testObject);
System.out.println("Serialized: " + json);
// Deserialize
Object result = mapper.readValue(json, type);
// Basic equality check
if (!testObject.equals(result)) {
System.out.println("Warning: Serialization round-trip changed object");
System.out.println("Original: " + testObject);
System.out.println("Result: " + result);
} else {
System.out.println("Round-trip test passed for " + type.getSimpleName());
}
} catch (Exception e) {
throw new RuntimeException("Round-trip test failed for " + type.getSimpleName(), e);
}
}
}
// Usage in tests
@Test
public void testCustomModule() {
CustomTypesModule module = new CustomTypesModule();
ModuleTestUtils.testModuleRegistration(module);
Money testMoney = new Money("USD", new BigDecimal("123.45"));
ModuleTestUtils.testSerializationRoundTrip(module, testMoney, Money.class);
}// Module finder utilities
public class JacksonModules {
public static List<Module> findModules();
public static List<Module> findModules(ClassLoader classLoader);
public static void registerWellKnownModules(ObjectMapper mapper);
}
// Version information for modules
public class Version implements Comparable<Version>, Serializable {
public Version(int major, int minor, int patchLevel, String snapshotInfo, String groupId, String artifactId);
public int getMajorVersion();
public int getMinorVersion();
public int getPatchLevel();
public String getGroupId();
public String getArtifactId();
public boolean isSnapshot();
public boolean isUnknownVersion();
public static Version unknownVersion();
public String toString();
public int compareTo(Version other);
}
// Versioned interface for components
public interface Versioned {
Version version();
}
// Delegating deserializer base class
public abstract class DelegatingDeserializer extends JsonDeserializer<Object> implements ContextualDeserializer, ResolvableDeserializer {
protected final JsonDeserializer<?> _delegatee;
protected DelegatingDeserializer(JsonDeserializer<?> delegatee);
protected abstract JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDelegatee);
public JsonDeserializer<?> getDelegatee();
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException;
public Object deserialize(JsonParser p, DeserializationContext ctxt, Object intoValue) throws IOException;
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException;
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException;
public void resolve(DeserializationContext ctxt) throws JsonMappingException;
}
// Delegating serializer base class
public abstract class DelegatingSerializer extends JsonSerializer<Object> implements ContextualSerializer, ResolvableSerializer {
protected final JsonSerializer<Object> _delegatee;
protected DelegatingSerializer(JsonSerializer<?> delegatee);
protected abstract JsonSerializer<?> newDelegatingInstance(JsonSerializer<?> newDelegatee);
public JsonSerializer<?> getDelegatee();
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException;
public void serializeWithType(Object value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException;
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException;
public void resolve(SerializerProvider provider) throws JsonMappingException;
}
// Named type for subtype registration
public class NamedType implements Serializable {
public NamedType(Class<?> c);
public NamedType(Class<?> c, String name);
public Class<?> getType();
public String getName();
public boolean hasName();
public boolean equals(Object o);
public int hashCode();
public String toString();
}Install with Tessl CLI
npx tessl i tessl/maven-com-fasterxml-jackson-core--jackson-databind