У меня есть класс, который выглядит так:
@JsonDeserialize(builder=ContainerBuilder.class)
class Container {
@JsonSerializer(using=MySerializer.class)
@JsonDeserializer(using=MyDeserializer.class)
ThirdPartyMap<MyKey, MyValue> map;
}
Мне нужен собственный сериализатор, потому что ключи в моей карте имеют структуру, а Джексон по умолчанию создает поле с key.toString()
в качестве имени поля.
Я хотел бы сделать мой десериализатор универсальным, а не жестко кодировать MyKey
и MyValue
как типы карты. В файле класса хранятся общие типы поля, поэтому я ожидаю, что смогу получить эту информацию. Однако я не смог найти его.
Я нашел Пользовательский десериализатор Джексона, получающий доступ к текущему классу поля, который рекомендовал использовать JsonParser.getCurrentValue()
для (я думаю) получения экземпляра возвращаемого значения и использования отражения для поиска поля. Однако, поскольку класс, который я десериализую, является окончательным и создан с помощью компоновщика, getCurrentValue
возвращает значение null.
Также похоже, что deserializeWithType
может иметь значение, но я не могу понять, как вызвать этот метод.
Изменить: стирание типа не полностью стирает дженерики во время выполнения. Если у меня есть Map<String, Integer>
, то, глядя на объект, стирание мешает мне узнать общие параметры.
Однако если у меня есть такой класс, как interface Data { Collection<String> getList() }
, общая информация о возвращаемом типе является частью класса. Действительно, он должен быть в файле класса, иначе я мог бы поместить класс в файл jar и использовать его так: Collection<Integer> c = data.getList();
и компилятор не знал бы, что выдает ошибку компиляции.
Джексон должен читать информацию о классе, чтобы знать тип поля, поэтому он должен (по крайней мере, в принципе) также иметь возможность получать общие параметры для типа. Делает ли он это и делает ли это так, чтобы он был доступен для пользовательского десериализатора, — это отдельный вопрос, и основной вопрос здесь.