我编写了一个简单的测试应用程序,它从数据库中读取记录并将结果放入csv文件中。到目前为止它工作正常,但列名称,标题不会放在csv文件中。根据文件,它应该放在那里。我也尝试过没有/流媒体和分裂,但情况是一样的。
在第182行的驼峰单元测试中,标题明确地放在那里:https://github.com/apache/camel/blob/master/components/camel-csv/src/test/java/org/apache/camel/dataformat/csv/CsvDataFormatTest.java
如果不需要迭代标题,如何解决这个非常简单的问题?我也尝试了不同的设置,但都是一样的。这样的分隔符已被认为是我设置但标题不是。也提前感谢您的回复。
我像这样使用Camel 2.16.1:
final CsvDataFormat csvDataFormat = new CsvDataFormat();
csvDataFormat.setHeaderDisabled(false);
[...]
from("direct:TEST").routeId("TEST")
.setBody(constant("SELECT * FROM MYTABLE"))
.to("jdbc:myDataSource?readSize=100") // max 100 records
// .split(simple("${body}")) // split the list
// .streaming() // not to keep all messages in memory
.marshal(csvDataFormat)
.to("file:extract?fileName=TEST.csv");
[...]
编辑1
我还试图从exchange.in添加标题。它们在HashSet中可以使用名称“CamelJdbcColumnNames”。我将它添加到csvDataFormat中:
final CsvDataFormat csvDataFormat = new CsvDataFormat();
csvDataFormat.setHeaderDisabled(false);
[...]
from("direct:TEST").routeId("TEST")
.setBody(constant("SELECT * FROM MYTABLE"))
.to("jdbc:myDataSource?readSize=100") // max 100 records
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
headerNames = (HashSet)exchange.getIn().getHeader("CamelJdbcColumnNames");
System.out.println("#### Process headernames = " + new ArrayList<String>(headerNames).toString());
csvDataFormat.setHeader(new ArrayList<String>(headerNames));
}
})
.marshal(csvDataFormat)//.tracing()
.to("file:extract?fileName=TEST.csv");
println()打印列名,但生成的cvs文件不打印。
EDIT2 我按照评论1中的建议将标题名称添加到正文中:
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
Set<String> headerNames = (HashSet)exchange.getIn().getHeader("CamelJdbcColumnNames");
Map<String, String> nameMap = new LinkedHashMap<String, String>();
for (String name: headerNames){
nameMap.put(name, name);
}
List<Map> listWithHeaders = new ArrayList<Map>();
listWithHeaders.add(nameMap);
List<Map> records = exchange.getIn().getBody(List.class);
listWithHeaders.addAll(records);
exchange.getIn().setBody(listWithHeaders, List.class);
System.out.println("#### Process headernames = " + new ArrayList<String>(headerNames).toString());
csvDataFormat.setHeader(new ArrayList<String>(headerNames));
}
})
该提案解决了问题并感谢您,但这意味着CsvDataFormat并不真正可用。 JDBC查询后的交换体包含来自HashMaps的ArrayList,其中包含该表的一条记录。 HashMap的键是列的名称,值是值。因此,在CsvDataFormat中设置标头输出的配置值应该足以获得生成的标头。你知道一个更简单的解决方案,还是我错过了配置中的一些东西?
答案 0 :(得分:1)
您使用JDBC从数据库中获取数据,因此您需要先自己将标题添加到消息正文中,以便将其添加到第一行。来自jdbc的结果集只是数据,不包括标题。
答案 1 :(得分:0)
我使用spring xml的解决方案(但我想在顶部也提取标题:
使用spring xml
<multicast stopOnException="true">
<pipeline>
<log message="saving table ${headers.tablename} header to ${headers.CamelFileName}..."/>
<setBody>
<groovy>request.headers.get('CamelJdbcColumnNames').join(";") + "\n"</groovy>
</setBody>
<to uri="file:output"/>
</pipeline>
<pipeline>
<log message="saving table ${headers.tablename} rows to ${headers.CamelFileName}..."/>
<marshal>
<csv delimiter=";" headerDisabled="false" useMaps="true"/>
</marshal>
<to uri="file:output?fileExist=Append"/>
</pipeline>
</multicast>