2

我的 CSV 文件总是包含相同的字段或相同字段的子集。但是,它们来自不同的提供商,并且每个提供商都有不同的顺序。此外,如果该字段为空,则某些提供商会包含该字段,而其他提供商则将其删除。样本:

提供者 1.txt:

id,name,address,url
3,ruth,ruth address,ruth.com
B,sonia,sonia's street, thisissonia.eu

提供者 2.txt:

id,url,name
3,shutupmag.com,maggie
B,khaleesi.org,Mother of Dragons

第一行始终是标题,并且标题始终相同(可能会省略一个或多个)。

我正在使用 Camel Route 进行处理,使用 Bindy 和带注释的类进行编组/解组。我对我的解决方案很满意,但是现在当我想处理不同的提供者时,我必须手动编辑 Bean 中字段的顺序。我的 Bean 中有这样的东西:

@DataField(pos = 4, defaultValue = "") //for provider Stark
//@DataField(pos = 2, defaultValue = "") //for provider Lannister
//@DataField(pos = 3, defaultValue = "") //for provider Targaryen
public String url = "";

感觉很糟糕,我认为可能有一种方法可以从第一行推断字段。至少这是有道理的。我可以在处理器中做到这一点,但我喜欢 Bindy,它很棒,我想继续使用它。我想我可以为每个提供者使用不同的文件夹,并为每个文件夹使用不同的 bean,但这也不是我想要的。提供者可以更改顺序或字段,恕不另行通知。但他们总是需要在第一行发送字段。

所以最后一个问题:我可以使用Bindy (或其他组件,我愿意接受建议,我只是更喜欢继续使用Bindy)自动检测Camel中的CSV字段名称吗?

4

1 回答 1

2

或者,您可以使用Camel CSV 组件。您没有得到完全初始化的值 bean,而是一个包含键值对的映射列表:

final CsvDataFormat format = new CsvDataFormat();
format.setUseMaps(true);
format.setDelimiter(",");

from("direct:start")
    .unmarshal(format)
    .process(new Processor() {
        @Override
        public void process(final Exchange exchange) throws Exception {
            final List<Map<String, String>> body = exchange.getIn().getBody(List.class);
            for (final Map<String, String> row : body) {
                LOG.info("new row: {}", row);
            }
        }
    });

和:

template.sendBody("direct:start", "id,name,address,url\n3,ruth,ruth address,ruth.com\nB,sonia,sonia's street, thisissonia.eu");
template.sendBody("direct:start", "id,url,name\n3,shutupmag.com,maggie\nB,khaleesi.org,Mother of Dragons"); 

你得到以下输出:

new row: {id=3, address=ruth address, url=ruth.com, name=ruth}
new row: {id=B, address=sonia's street, url=thisissonia.eu, name=sonia}
new row: {id=3, url=shutupmag.com, name=maggie}
new row: {id=B, url=khaleesi.org, name=Mother of Dragons}   
于 2014-09-01T20:11:25.843 回答