Джексон - Пользовательский Резолвер TypeId

Я использовал собственный распознаватель typeId для одного из моих классов, и до сих пор опирался на поддержку аннотаций:

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

Но теперь мне нужно настроить создание распознавателя типов, передав ему некоторые другие зависимости через конструктор или сеттеры, и, поскольку именно Джексон создает его, я не могу найти способ обойти это.

Есть ли способ настроить ObjectMapper для использования TypeIdResolver вместо того, чтобы полагаться на аннотации?

С уважением

1 ответ

Решение

Итак, у вас есть два варианта:

1) Если вы настроены на использование @JsonTypeIdResolver вы застряли с помощью static состояние в вашем TypeIdResolver, Это, вероятно, не то, что вы хотите.

По умолчанию JacksonAnnotationIntrospector попытается создать экземпляр типа, который вы предоставляете, используя JsonTypeIdResolver согласно его конструктору по умолчанию. В настоящее время нет способа настроить его, чтобы сделать иначе.

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) Создайте модуль для десериализации вашего типа и подтипов.

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);

Для более подробных примеров см. Документацию Джексона. Практические руководства. Пользовательские десериализаторы.

Вы также можете программно установить преобразователь идентификатора пользовательского типа. Посмотрите на главный ответ здесь. Ищите эту строку:

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

Заменить null с помощью преобразователя идентификатора вашего типа.

Другие вопросы по тегам