Camel bindy 编组到文件创建多个 header 行

Camel bindy marshal to file creates multiple header row

我有以下骆驼路线:

from(inputDirectory)
  .unmarshal(jaxb)
  .process(jaxb2CSVDataProcessor)
  .split(body()) //because there is a list of CSVRecords
  .marshal(bindyCsvDataFormat)
  .to(outputDirectory); //appending to existing file using "?autoCreate=true&fileExist=Append"

对于我的 CSV 模型 class 我正在使用注释:

@CsvRecord(separator = ",", generateHeaderColumns = true)
...

和属性

@DataField(pos = 0)
...

我的问题是每次附加新的 csv 记录时都会附加 headers。

有没有non-dirty方法来控制这个?我在这里遗漏了什么吗?

我最后添加了一个处理器来检查 csv 文件是否存在于 "to" 子句之前。在那里我对字节数组进行了操作并删除了 headers.

我做了一个很好的工作,通过查询@DataField 注释的列名创建 header。这是第一次写入文件时发生的情况。我在这里写下了整个解决方案:

How to generate a Flat file with header and footer using Camel Bindy

希望这对其他人有帮助。我需要做一些类似的事情,在我的第一个拆分消息之后我想抑制 header 输出。这是一个完整的 class('FieldUtils' 是 apache 公共库的一部分)

package com.routes;

import java.io.OutputStream;

import org.apache.camel.Exchange;
import org.apache.camel.dataformat.bindy.BindyAbstractFactory;
import org.apache.camel.dataformat.bindy.BindyCsvFactory;
import org.apache.camel.dataformat.bindy.BindyFactory;
import org.apache.camel.dataformat.bindy.FormatFactory;
import org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat;
import org.apache.commons.lang3.reflect.FieldUtils;

public class StreamingBindyCsvDataFormat extends BindyCsvDataFormat {

    public StreamingBindyCsvDataFormat(Class<?> type) {
        super(type);
    }

    @Override
    public void marshal(Exchange exchange, Object body, OutputStream outputStream) throws Exception {
        final StreamingBindyModelFactory factory = (StreamingBindyModelFactory) super.getFactory();
        final int splitIndex = exchange.getProperty(Exchange.SPLIT_INDEX, -1, int.class);
        final boolean splitComplete = exchange.getProperty(Exchange.SPLIT_COMPLETE, false, boolean.class);

        super.marshal(exchange, body, outputStream);

        if (splitIndex == 0) {
        factory.setGenerateHeaderColumnNames(false); // turn off header generate after first exchange
        } else if(splitComplete) {
        factory.setGenerateHeaderColumnNames(true); // turn on header generate when split complete
        }
    }

    @Override
    protected BindyAbstractFactory createModelFactory(FormatFactory formatFactory) throws Exception {
        BindyCsvFactory bindyCsvFactory = new StreamingBindyModelFactory(getClassType());
        bindyCsvFactory.setFormatFactory(formatFactory);
        return bindyCsvFactory;
    }

    public class StreamingBindyModelFactory extends BindyCsvFactory implements BindyFactory {

        public StreamingBindyModelFactory(Class<?> type) throws Exception {
            super(type);
        }

        public void setGenerateHeaderColumnNames(boolean generateHeaderColumnNames) throws IllegalAccessException {
            FieldUtils.writeField(this, "generateHeaderColumnNames", generateHeaderColumnNames, true);
        }

    }

}