我有一个单行csv,第二个值由多行组成:
field1,"this
is still
field2","field3"
我希望使用Apache Camel,它是一个像这样的json(解析文件后):
{"field1":"field1","field2":"this
is still
field2","field3":"field3"}
但使用以下代码:
from('something...')
.transform(simple('/path/demooneline.csv', File.class))
.unmarshal().bindy(BindyType.Csv, Demo.class)
.marshal().json(JsonLibrary.Jackson).log('${body}')
@CsvRecord(separator = ',')
class Demo {
@JsonView
@DataField(pos = 1)
private String field1
@JsonView
@DataField(pos = 2)
private String field2
@JsonView
@DataField(pos = 3)
private String field3
}
我回来了:
{"field1":"field1","field2":"this","field3":null},
{"field1":"is still","field2":null,"field3":null},
{"field1":null,"field2":"field3","field3":null}
看起来csv分为3行,而不是1行,其中一些字段用引号分隔。 @CsvRecord有"引用"作为默认值。有没有办法用Camel解析那种CSV(使用或不使用bindy)?
答案 0 :(得分:3)
问题是您的CSV文件不是典型的"。来自Wikipidia:
" CSV"不是单一的,定义良好的格式(尽管通常使用的是一个定义的RFC 4180)。相反,在实践中,术语" CSV"指任何文件:
- 是使用ASCII,Unicode,EBCDIC或Shift JIS等字符集的纯文本,
- 由记录(通常每行一条记录),
组成- 将记录划分为由分隔符分隔的字段(通常是单个保留字符,如逗号,分号或制表符;有时分隔符可能包含可选空格),
- 其中每条记录都有相同的字段序列。
醇>
在你的情况下,你的记录跨越多行,这就是为什么Camel没有像你期望的那样解析它,Camel假设每行都是不同的记录。
修改强>
正如我在评论中提到的,看起来Camel Bindy不处理包含换行符的引用字段。作为一种解决方法,您可以预处理"源CSV文件替换qoutes内的换行符。例如,使用Guava:
from("file:///csvSrcDir?noop=true")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
final String inBody = exchange.getIn().getBody(String.class);
final Iterable<String> tokens = Splitter.on("\",").split(inBody);
final Iterable<String> fixedTokens = FluentIterable.from(tokens).transform(new Function<String, String>() {
@Nullable
@Override
public String apply(String input) {
return input.contains("\"\n") ? input : input.replace("\n", "<br>");
}
});
final String outBody = Joiner.on("\",").join(fixedTokens);
exchange.getOut().setBody(outBody);
}
})
.unmarshal().bindy(BindyType.Csv, Demo.class)
.split(body())
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
Demo body = exchange.getIn().getBody(Demo.class);
}
});
自定义处理器转换此CSV文件:
"record 1 field1","this
is still
record 1 field2","record 1 field3"
"record 2 field1","this
is still
record line 2 field2","record 2 field3"
归档:
"record 1 field1","this<br><br>is still<br><br> record 1 field2","record 1 field3"
"record 2 field1","this<br><br>is still<br><br> record 2 field2","record 2 field3"
Bindy
可以处理。