8

I've been using a custom typeId resolver for one of my classes, so far I've been leaning on the annotation support:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.CUSTOM,
    include = JsonTypeInfo.As.PROPERTY,
    property = "@type")
@JsonTypeIdResolver(ColumnDefinitionTypeResolver.class)

But now I need to customize the creation of the type resolver by passing some other dependencies to it via constructor or setters, and since Jackson is the one who instantiate it I can't find a way around it.

Is there a way to configure the ObjectMapper to use a TypeIdResolver instead of relying on annotations?

Regards

Vinicius Carvalho
  • 3,994
  • 4
  • 23
  • 29

2 Answers2

5

So you have two options:

1) If you're set on using the @JsonTypeIdResolver your stuck using static state in your TypeIdResolver. This probably isn't what you want.

The default JacksonAnnotationIntrospector will try to create an instance of the type you provide using JsonTypeIdResolver per its default constructor. There is currently no way to configure it to do otherwise.

public final class ColumnDefinitionTypeResolver implements TypeIdResolver {
  // You could rely on static state.
  public static String SOME_ACCESSIBLE_OBJECT = null;

  public ColumnDefinitionTypeResolver() {
    // This is what gets called.
  }
}

ColumnDefinitionTypeResolver.SOME_ACCESSIBLE_OBJECT = "I can affect the implementation from here, but using static state ... be careful";

2) Is create a module to handle deserialization of your type and subtypes.

SimpleModule columnDefinitionModule = new SimpleModule("colDefMod", new Version(1, 0, 0, null))
      .addDeserializer(ColumnDefinition.class, new JsonDeserializer() {
           @Override
           public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,  JsonProcessingException {
                // Need to read the type out and then use ObjectMapper to deserialize using the correct token
            }
        })
        .registerSubtypes(...); // add your subtypes here.

(new ObjectMapper()).registerModule(columnDefinitionModule);

For more detailed examples, see Jackson documentation How-To: Custom Deserializers.

vpiTriumph
  • 3,116
  • 2
  • 27
  • 39
  • 1
    "There is currently no way to configure it to do otherwise."... now in 2022 there is a way... you can provide your own `HandlerInstantiator` to create or provide the `TypeIdResolver` – Robert Feb 24 '22 at 12:28
1

You can also set a custom type id resolver programmatically. Look at the top answer here. Look for this line:

typeResolver.init(JsonTypeInfo.Id.CLASS, null);

Replace null with your type id resolver.

bertilmuth
  • 276
  • 1
  • 11