У меня проблема, похожая на эту: Kafka десериализует вложенные универсальные типы В моем производителе kafka я отправляю объект, который выглядит так:
public class ExternalTO implements Serializable
{
private static final long serialVersionUID = 7949808917892350503L;
private List<IExternalData> externalDatas;
public ExternalTO()
{}
}
Краеугольный камень в этом: List<IExternalData> externalDatas.
Этот интерфейс выглядит так:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public interface IExternalData
{
String getOne();
}
В моем приложении может быть создано несколько типов реализаций интерфейса IExternalBetData (около 10 различных). В этом случае, например, мой производитель сгенерировал ExternalTO с внутренним списком объектов ConcreteExternalData. Отправленный JSON выглядит так:
{
"externalDatas":
[{"@class":"com.api.external.to.ConcreteExternalData",
"one":false,
"two":false}]
}
Поле @class было добавлено из-за аннотации @JsonTypeInfo, и я подумал, что этого достаточно для десериализатора, чтобы «понять», какой тип IExternalData использовать при десериализации. К сожалению, на стороне слушателя кафки я получаю исключение:
Cannot construct instance of
com.api.external.to.IExternalData(no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
Потребитель похож на:
@Service
public class Consumer
{
private final ObjectMapper objectMapper;
public Consumer(ObjectMapper objectMapper)
{
this.objectMapper = objectMapper;
}
@KafkaListener(topics = {"${kafka.topic}"})
public void listen(ConsumerRecord<String, String> record)
{
objectMapper.readValue(record.value(), ExternalTO.class)
}
Помогите решить этот вопрос с десериатизацией.




Из всех реализаций IExternalData десериализатор не знает, в какую из них следует десериализовать данные записи потребителя. Мы должны разрешить эту двусмысленность.
Я смог решить эту проблему с помощью аннотации @JsonDeserialize.
@ JsonDeserialize (as = <Выполнение> .class
над объявлением Списка
Решением для меня было установить свойство в objectMapper.
ObjectMapper mapper = new ObjectMapper();
// deserializes IExternalData into certain implementation.
mapper.enableDefaultTyping();