添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Spring's Kafka producer embeds type header into messages which specifies to which class the message should be deserialized by a consumer.This is a problem when the producer isn't using Spring Kafka, but the consumer is.In that case, JsonDeserializer cannot deserialize a message and will throw an exception "No type information in headers and no default type provided".
One way to get around this is to set a default deserialization type.This won't work in cases where a single topic contains multiple message schemas. Another solution I've found is to set

spring.kafka.consumer.properties.spring.json.use.type.headers

to false (in application.properties file).This doesn't do anything as the same exception is thrown again.
How do I make sure that JsonDeserializer ignores type headers?

See this option of that deserializer:

* Set to false to ignore type information in headers and use the configured * target type instead. * Only applies if the preconfigured type mapper is used. * Default true. * @param useTypeHeaders false to ignore type headers. * @since 2.2.8 public void setUseTypeHeaders(boolean useTypeHeaders) {

It can be configured via property as:

* Kafka config property for using type headers (default true). * @since 2.2.3 public static final String USE_TYPE_INFO_HEADERS = "spring.json.use.type.headers";

In this case the logic is going to be like this:

this.typeMapper.setTypePrecedence(this.useTypeHeaders ? TypePrecedence.TYPE_ID : TypePrecedence.INFERRED);

which means that the type for deserialization is inferred from the listener method.

See more info in docs: https://docs.spring.io/spring-kafka/reference/html/#json-serde

The deserializer can't infer the type from the method signature; only the message converter can do that; with the deserializer you have to provide the default type via a property. docs.spring.io/spring-kafka/docs/current/reference/html/… JsonDeserializer.VALUE_DEFAULT_TYPE: Fallback type for deserialization of values if no header information is present. – Gary Russell Jul 25, 2022 at 14:20 To infer the type from the listener method, use a ByteArrayDeserializer with a JsonMessageConverter docs.spring.io/spring-kafka/docs/current/reference/html/… – Gary Russell Jul 25, 2022 at 14:26 So where do I tell the deserializer to not use type header?Setting spring.json.use.type.headers to false in application.properties doesn't do anything.Is there any way to use Spring boot's auto configuration and avoid creating a new factory for every listener?It's fascinating how difficult it is to change such basic property.These type headers shouldn't even exist. – The light one Jul 25, 2022 at 14:35 It's not "using the headers" See the error message No type information in headers and no default type provided - there is no type information, so you need to set spring.kafka.consumer.properties.spring.json.value.default.type=com.demo.MyDto. – Gary Russell Jul 25, 2022 at 15:14 If you are using @KafkaListener you can override that property for each listener or, as I said, use a ByteArrayDeserializer and add a JsonMessageConverter bean which Boot will automatically wire into the container factory and the type will be inferred from the method signature. – Gary Russell Jul 25, 2022 at 15:16

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.