[英]Spring boot Kafka class deserialization - not in the trusted package
我知道這個問題非常普遍,但是按照不同的解決方案,我找不到任何可行的解決方案。 在Kafka中接收消息時,我想反序列化字符串以及我的自定義類對象。 使用String會很好,但不能使用我的Class。 我在使用者配置中添加了受信任的程序包( com.springmiddleware.entities
是我的課程所在的程序包):
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
props.put(ConsumerConfig.GROUP_ID_CONFIG, "foo");
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
props.put(JsonDeserializer.TRUSTED_PACKAGES, "com.springmiddleware.entities");
return props;
}
我的application.yml
文件中有此文件:
spring:
kafka:
bootstrap-servers: localhost:9092
consumer:
group-id: foo
auto-offset-reset: earliest
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
properties:
spring:
json:
trusted:
packages: 'com.springmiddleware.entities'
並將這些行添加到application.properties
spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.properties.spring.json.trusted.packages=com.springmiddleware.entities
spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
spring.kafka.producer.properties.spring.json.add.type.headers=false
但是以下錯誤一直顯示:
org.apache.kafka.common.errors.SerializationException:在偏移量1處反序列化分區topic2-0的鍵/值時出錯。如果需要,請查找記錄以繼續使用。 由以下原因引起:java.lang.IllegalArgumentException:可信包[java.util,java.lang]中沒有'com.springmiddleware.entities.Crime'類。 如果您認為該類別可以安全地反序列化,請提供其名稱。 如果序列化僅由受信任的源完成,則還可以啟用全部信任(*)。
UPDATE
ReceiverConfig:
@EnableKafka
@Configuration
public class ReceiverConfig {
@Value("${spring.kafka.bootstrap-servers}")
private String bootstrapServers;
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
props.put(ConsumerConfig.GROUP_ID_CONFIG, "foo");
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
props.put(JsonDeserializer.TRUSTED_PACKAGES, "com.springmiddleware.entities");
props.put(JsonDeserializer.USE_TYPE_INFO_HEADERS, "false");
return props;
}
@Bean
public ConsumerFactory<String, Object> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(consumerConfigs(), new StringDeserializer(),
new JsonDeserializer<>());
}
@Bean
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, Object>> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
return factory;
}
更新2
Listener Class (Receiver):
@KafkaListener(topics = "${app.topic.foo}")
@Service
public class Receiver {
private CountDownLatch latch = new CountDownLatch(1);
public CountDownLatch getLatch() {
return latch;
}
@KafkaHandler
public void listen(@Payload Crime message) {
System.out.println("Received " + message);
}
@KafkaHandler
public void listen(@Payload String message) {
System.out.println("Received " + message);
}
只需使用Overloaded JsonDeserializer
構造函數
從2.2版開始,您可以使用具有boolean useHeadersIfPresent(默認為true)的重載構造函數之一,將反序列化器顯式配置為使用提供的目標類型,並忽略標頭中的類型信息。
以下示例顯示了如何執行此操作:
DefaultKafkaConsumerFactory<Integer, Cat1> cf = new DefaultKafkaConsumerFactory<>(props,
new IntegerDeserializer(), new JsonDeserializer<>(Cat1.class, false));
您的代碼:
@Bean
public ConsumerFactory<String, Object> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(consumerConfigs(), new StringDeserializer(),
new JsonDeserializer<>(Object.class,false));
}
現在在類級別使用@KafkaListener
@KafkaListener(topics = "myTopic")
@Service
public class MultiListenerBean {
@KafkaHandler
public void listen(Cat cat) {
...
}
@KafkaHandler
public void listen(Hat hat) {
...
}
@KafkaHandler(isDefault = true)
public void delete(Object obj) {
...
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.