Spring boot 该类不在受信任的包中,但显示在受信任的包列表中

Spring boot 该类不在受信任的包中,但显示在受信任的包列表中,spring-boot,spring-kafka,Spring Boot,Spring Kafka,我正在尝试在两个不同的Spring Boot应用程序之间实现一个简单的Kafka通信,没有任何特殊设置,这个应用程序只有一个kafkalistener。我对消费者的yml如下所示: spring: kafka: bootstrap-servers: ip_here topic: json: topic_here consumer: group-id: group_id auto-offset-reset: earliest

我正在尝试在两个不同的Spring Boot应用程序之间实现一个简单的Kafka通信,没有任何特殊设置,这个应用程序只有一个kafkalistener。我对消费者的yml如下所示:

spring:
  kafka:
    bootstrap-servers: ip_here
    topic:
      json: topic_here
    consumer:
      group-id: group_id
      auto-offset-reset: earliest
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      properties:
        spring:
          json:
            trusted:
              packages: 'com.example.kw.dtos.Classdata'
我收到的错误如下:

spring:
  kafka:
    bootstrap-servers: ip_here
    topic:
      json: topic_here
    consumer:
      group-id: group_id
      auto-offset-reset: earliest
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      properties:
        spring:
          json:
            trusted:
              packages: 'com.example.kw.dtos.Classdata'
原因:java.lang.IllegalArgumentException:类 “com.example.kw.dtos.Classdata”不在受信任的包中: [java.util、java.lang、com.example.kw.dtos.Classdata]。如果你相信 此类可以安全地反序列化,请提供其名称。如果 序列化仅由受信任的源完成,您还可以启用 信任所有(*)

该包位于受信任的包中,但出现问题

我的工厂班级:

@Configuration
@EnableKafka
public class MsgListener {

    @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, "json");
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        props.put(JsonDeserializer.TRUSTED_PACKAGES, "com.example.kw.dtos.Classdata");
        return props;
    }

    @Bean
    public ConsumerFactory<String, Classdata> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(
                consumerConfigs(),
                new StringDeserializer(),
                new JsonDeserializer<>(Classdata.class));
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, Classdata> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, Classdata> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        return factory;
    }
}
@配置
@使能卡夫卡
公共级MsgListener{
@值(${spring.kafka.bootstrap servers}”)
私有字符串引导服务器;
@豆子
公共地图使用者配置(){
Map props=newhashmap();
put(ConsumerConfig.BOOTSTRAP\u server\u CONFIG,bootstrapserver);
put(ConsumerConfig.KEY\u反序列化程序\u类\u配置,StringDeserializer.CLASS);
put(ConsumerConfig.VALUE\u反序列化程序\u类\u配置,JsonDeserializer.CLASS);
put(ConsumerConfig.GROUP_ID_CONFIG,“json”);
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,“最早”);
put(JsonDeserializer.TRUSTED_包,“com.example.kw.dtos.Classdata”);
返回道具;
}
@豆子
公共消费者工厂消费者工厂(){
返回新的DefaultKafka消费者工厂(
consumerConfigs(),
新建StringDeserializer(),
新的JsonDeserializer(Classdata.class));
}
@豆子
公共ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory(){
ConcurrentKafkalistener集装箱工厂=
新的ConcurrentKafkaListenerContainerFactory();
setConsumerFactory(consumerFactory());
返回工厂;
}
}

它应该只是包
com.example.kw.dtos

String packageName = ClassUtils.getPackageName(requestedType).replaceFirst("\\[L", "");
for (String trustedPackage : this.trustedPackages) {
    if (packageName.equals(trustedPackage)) {
        return true;
    }
}

我们在测试卡夫卡时遇到了这个问题。 我们这样做:

private static KafkaMessageListenerContainer<String, Data> createMessageListenerContainer() {
  final Map<String, Object> consumerProps = KafkaTestUtils.consumerProps("sender", "false", EMBEDDED_KAFKA);
  final DefaultKafkaConsumerFactory<String, Data> consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProps);

  final JsonDeserializer<Data> valueDeserializer = new JsonDeserializer<>();
  valueDeserializer.addTrustedPackages("path.to.package");

  consumerFactory.setValueDeserializer(valueDeserializer);
  consumerFactory.setKeyDeserializer(new StringDeserializer());

  final ContainerProperties containerProperties = new ContainerProperties(SENDER_TOPIC);
  return new KafkaMessageListenerContainer<>(consumerFactory, containerProperties);
}
私有静态KafkaMessageListenerContainer createMessageListenerContainer(){
最终映射ConsumerOps=KafkaTestUtils.ConsumerOps(“发送方”、“假”,嵌入卡夫卡);
最终默认卡夫卡消费工厂consumerFactory=新默认卡夫卡消费工厂(ConsumerOps);
final JsonDeserializer valueDeserializer=新JsonDeserializer();
valueDeserializer.addTrustedPackages(“path.to.package”);
setValueDeserializer(valueDeserializer);
setKeyDeserializer(新的StringDeserializer());
最终ContainerProperties ContainerProperties=新的ContainerProperty(发送方\主题);
返回新的KafkaMessageListenerContainer(消费者工厂、集装箱房地产);
}

这里的诀窍是你必须在两个地方设置它

  • spring.json.trusted.packages——用于在卡夫卡影响之外创建的任何json反序列化程序
  • spring.kafka.consumer.properties.spring.json.trusted.packages-用于kafka创建的反序列化程序

这是我唯一能让它工作的方法。此外,它不接受通配符,因此它必须是精确的包匹配

您在哪里使用trusted packages属性?我没有在任何地方使用它。您是否可以在创建kafka consumer factory的位置添加代码?我刚刚添加了一个factory类。它不见了。受信任的包是否也应该存在于producer中???是否创建java对象的json表示,然后生成,然后,当使用从json字符串转换回java对象时?这确实有效,但现在因为我使用的是不同的包名,所以有一个MessageConversionException:无法解析类名。当使用与生产者发送的对象不同的
@KafkaListener
时,您应该将
StringJsonMessageConverter
StringDeserializer
ByteArraydSerializer
一起使用,而不是使用
JsonDeserializer
-请参阅。实际参数类型被传递到转换器中。