当前位置: 首页 > 知识库问答 >
问题:

无法解码Spring Cloud数据流中key:file_name的json类型

禄星腾
2023-03-14

我使用Spring Cloud Data Flow设置一个读取CSV文件的流,使用自定义处理器对其进行转换并记录:

stream create --name testsourcecsv --definition "file --mode=lines --directory=D:/toto/ --file.filename-pattern=adresses-28.csv --maxMessages=1000 | csvToMap --spring.cloud.stream.bindings.output.content-type=application/json | log --spring.cloud.stream.bindings.input.content-type=application/json" --deploy

文件和csvToMap应用程序工作正常,但在日志应用程序中,我看到这种异常,对于每条记录:

2019-12-03 11:32:46.500 ERROR 1328 --- [container-0-C-1] o.s.c.s.b.k.KafkaMessageChannelBinder$5  : Could not decode json type: adresses-28.csv for key: file_name

com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'adresses': was expecting ('true', 'false' or 'null')
 at [Source: (byte[])"adresses-28.csv"; line: 1, column: 10]
    at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1804) ~[jackson-core-2.9.9.jar!/:2.9.9]
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:703) ~[jackson-core-2.9.9.jar!/:2.9.9]
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidToken(UTF8StreamJsonParser.java:3532) ~[jackson-core-2.9.9.jar!/:2.9.9]
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2627) ~[jackson-core-2.9.9.jar!/:2.9.9]
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:832) ~[jackson-core-2.9.9.jar!/:2.9.9]
    at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:729) ~[jackson-core-2.9.9.jar!/:2.9.9]
    at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4141) ~[jackson-databind-2.9.9.jar!/:2.9.9]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4000) ~[jackson-databind-2.9.9.jar!/:2.9.9]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3091) ~[jackson-databind-2.9.9.jar!/:2.9.9]
    at org.springframework.cloud.stream.binder.kafka.BinderHeaderMapper.lambda$toHeaders$1(BinderHeaderMapper.java:268) ~[spring-cloud-stream-binder-kafka-2.1.4.RELEASE.jar!/:2.1.4.RELEASE]
    at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_202]
    at org.springframework.cloud.stream.binder.kafka.BinderHeaderMapper.toHeaders(BinderHeaderMapper.java:251) ~[spring-cloud-stream-binder-kafka-2.1.4.RELEASE.jar!/:2.1.4.RELEASE]

对于file\u relativePath标头,也会引发此异常。我不明白为什么斯普林·Kafka试图将它们解读为JSON。

此外,日志接收器以正确的方式记录我的记录:

2019-12-03 11:32:46.516  INFO 1328 --- [container-0-C-1] log-sink                                 : {"code_postal":"28200","id_fantoir":"28211_0127","source_nom_voie":"inconnue","numero":"1","code_insee":28211,"lon":1.260462,"code_insee_ancienne_commune":"","nom_afnor":"RUE DU VIEUX MOULIN","nom_voie":"Rue du Vieux Moulin","nom_ld":"","libelle_acheminement":"LOGRON","source_position":"inconnue","nom_commune":"Logron","nom_ancienne_commune":"","x":570633.27,"y":6784246.2,"alias":"","id":"28211_0127_00001","rep":"","lat":48.145756}

出于调试目的,我将kafka头记录在csvToMap处理器中,给出:

2019-12-03 11:32:37.042  INFO 10788 --- [container-0-C-1] c.d.streams.processor.CsvToMapProcessor  : headers {sequenceNumber=152963, file_name=adresses-28.csv, sequenceSize=0, deliveryAttempt=1, kafka_timestampType=CREATE_TIME, file_originalFile=NonTrustedHeaderType [headerValue="D:\\toto\\adresses-28.csv", untrustedType=java.io.File], kafka_receivedMessageKey=null, kafka_receivedTopic=testsourcecsv.file, file_relativePath=adresses-28.csv, kafka_offset=430949, scst_nativeHeadersPresent=true, kafka_consumer=org.apache.kafka.clients.consumer.KafkaConsumer@7c3e63db, correlationId=9547c02d-e617-d981-f9b5-8df231530f66, kafka_receivedPartitionId=0, contentType=text/plain, kafka_receivedTimestamp=1575299282558, kafka_groupId=testsourcecsv}

所以我完全不明白为什么日志接收器试图解码file_name和file_relativePath标头。

我设置了一个本地环境:

  • Windows 7
  • Spring CDF服务器版本2.2.1。REALEASE
  • Spring Cloud Skipper版本2.1.2。释放
  • SpringCDF外壳v 2.2.1。释放
  • Kafka2.12-2.3.0

我的csvToMap处理器定义如下:

    @Component
    public class CsvToMapProcessor {
        private static final Logger LOGGER = LoggerFactory.getLogger(CsvToMapProcessor.class);

        @Autowired
        @Qualifier("csvMapper")
        private ObjectReader csvMapper;

        @Autowired
        @Qualifier("jsonWriter")
        private ObjectWriter jsonWriter;

        @Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
        public Map<String, Object> transform(String csvLine, @Headers Map<String, Object> headers) {
            try {
                LOGGER.info("headers {}", headers);
                Map<String, Object> map = csvMapper.readValue(csvLine);
                return map;
            } catch (JsonProcessingException e) {
                LOGGER.error("An error occurs while reading CSV line {} : {}", csvLine, e.getMessage());
                LOGGER.debug(e.getMessage(), e);
                return null;
            }
        }
    }

使用此父级:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

而这个Spring云版本:

<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>

我做错了什么导致这个问题?

共有2个答案

白宏大
2023-03-14

它看起来像您在文件中设置的值。文件名模式有问题。能否检查您是否确实在传递遵循AntPathMatcher的值(filename模式属性基于此路径匹配器)?

如果您尝试类似于--file.filename模式=*. csv会发生什么?

朱锐
2023-03-14

因此:

  • 与spring cloud Hoxton版本相比,spring cloud stream版本为3.0.0。发布时间:
[INFO] +- org.springframework.cloud:spring-cloud-starter-stream-kafka:jar:3.0.0.RELEASE:compile
[INFO] |  \- org.springframework.cloud:spring-cloud-stream-binder-kafka:jar:3.0.0.RELEASE:compile
[INFO] |     +- org.springframework.cloud:spring-cloud-stream-binder-kafka-core:jar:3.0.0.RELEASE:compile
[INFO] |     |  \- org.springframework.integration:spring-integration-kafka:jar:3.2.1.RELEASE:compile
[INFO] |     \- org.springframework.kafka:spring-kafka:jar:2.3.3.RELEASE:compile
  • log sink app 2.1.2使用spring cloud stream v 2.1.4。发布时间:
[INFO] +- org.springframework.cloud:spring-cloud-starter-stream-kafka:jar:2.1.4.RELEASE:compile
[INFO] |  \- org.springframework.cloud:spring-cloud-stream-binder-kafka:jar:2.1.4.RELEASE:compile
[INFO] |     +- org.springframework.cloud:spring-cloud-stream-binder-kafka-core:jar:2.1.4.RELEASE:compile
[INFO] |     |  \- org.springframework.integration:spring-integration-kafka:jar:3.1.0.RELEASE:compile
[INFO] |     \- org.springframework.kafka:spring-kafka:jar:2.2.8.RELEASE:compile

正如spring-kafka 2.3.3留档DefaultKafkaHeaderMapper.setEncodeStrings方法所说:

如果出站记录的使用者正在使用Spring for Apache Kafka版本低于2.3,则设置为true

log sink应用程序实际上使用了spring kafka v 2.2.8,因此我必须使用自定义的头映射器将其设置为true:

    @Bean("kafkaBinderHeaderMapper")
    public KafkaHeaderMapper kafkaBinderHeaderMapper() {
        DefaultKafkaHeaderMapper mapper = new DefaultKafkaHeaderMapper();
        mapper.setEncodeStrings(true);
        return mapper;
    }

但如果我这样做,日志接收器不会记录任何内容,因为它无法理解DefaultKafkaHeaderMapper编码的contentType头。团队还提供了BinderHeaderMapper来解决此问题:

Apache Kafka的自定义标头映射器。这与Spring Kafka的DefaultKafkaHeaderMapper相同。这是为了解决Spring Cloud Stream 3.0. x和2. x应用程序之间的一些互操作性问题而提供的,其中在标头中作为常规MimeType传递的mime类型没有正确反序列化

所以我必须在我的应用程序中配置一个自定义的BinderHeaderMapper:

    @Bean("kafkaBinderHeaderMapper")
    public KafkaHeaderMapper kafkaBinderHeaderMapper() {
        BinderHeaderMapper mapper = new BinderHeaderMapper();
        mapper.setEncodeStrings(true);
        return mapper;
    }

一切正常。

 类似资料:
  • 我们正在使用spring cloud stream,并计划升级我们的Kafka版本 我们的应用程序使用apache kafka服务器的(spring kafka 2.1.7),还使用进行跟踪 我们将把Kafka服务器升级到,因此需要升级到与和 我们有约200个使用Kafka的应用程序,因此升级将逐步进行,因此作为中间状态,我们将有更新版本的生产者和使用旧版本的消费者 我们的消费者正在使用。 在我们

  • 需要一些建议,我已经使用scala创建了一个flink作业来消费来自Kafka的消息。但是消息是用base64编码压缩的。我已经试过这个代码了 代码由于它不是有效的Json格式而失败。 然后我尝试使用SimpleStringSchema(),就像下面的代码一样 Kafka的信息完美地消耗了,但是输出如下 如何将此数据解码为有效的JSON? 此致敬意

  • 在启动应用程序时,Kafka流出现了奇怪的错误 结果,关于失败流的错误:

  • 问题内容: 嘿,我不确定为什么每次选择图库中的图像时都会出现这种情况吗? 这是代码: 错误: 问题答案: 不要假设有文件路径。Android 4.4及更高版本即将删除它们。而且您获得的uri已经没有路径。 您仍然可以通过()或文件描述符访问文件内容。 在这里进行了解释:ContentProviders:打开一个文档(向下滚动,指向该节的链接似乎已损坏) 而且确实适用于较旧的android版本。

  • 问题内容: 我有一些大型的base64编码数据(存储在hadoop文件系统中的快照文件中)。该数据最初是压缩的文本数据。我需要能够读取此编码数据的大块,对其进行解码,然后将其刷新到GZIPOutputStream。 关于如何执行此操作而不是将整个base64数据加载到数组中并调用Base64.decodeBase64(byte [])的任何想法? 如果我读了直到’\ r \ n’分隔符并逐行解码的