How do I programmatically configure ObjectMapper in Java/Jackson to instantiate Java beans?

903 views Asked by At

I have a number of Java bean interfaces like this:

public interface Dog
{
String getName();
void setName( final String value );
}

I also auto-generate bean implementations like this:

public final class DogImpl implements Dog
{
public String getName()
{
    return m_name;
}

public void setName( final String value )
{
    m_value = value;
}

private volatile String m_value;
}

ObjectMapper works perfectly except when I start nesting these beans like this:

public interface Dog
{
String getName();
void setName( final String value );

Dog getParent();
void setParent( final Dog value );
}

I get this error:

abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information

It's complaining because the bean definition is an interface and not the concrete type. My question is if there is a way for me to define the mapping of interface types to concrete types for the ObjectMapper via a module or something?

Specifically, I can get a Map< Class< ? >, Class< ? > > of api type to implementation concrete type, but have no idea how to "give this" to the ObjectMapper so it understands how to look up the concrete types from the api types so it can instantiate them. How do I accomplish this?

1

There are 1 answers

0
jasons2645 On

This can be done using a SimpleAbstractTypeResolver.

This link shows you how to add the mappings to the resolver: Jackson - How to specify a single implementation for interface-referenced deserialization?


And this is how you add the resolver to an ObjectMapper:

        final SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver();
        for ( final Class< ? > api : apis )
        {
            resolver.addMapping( api, getConcreteImpl( api ) );
        }

        final SimpleModule module = new SimpleModule();
        module.setAbstractTypes( resolver );
        mapper.registerModule( module );