Apache Camel实现空行分隔键值对文本转POJO及CSV方案
解决方案
Bindy的KeyValue模式原生仅支持数字类型tag做键匹配,确实无法直接适配字符串键名的键值对格式,不需要硬适配该组件,以下是可直接落地的实现方式:
方案1:自定义处理器解析(最推荐,零额外依赖、逻辑可控)
第一步:修正原有路由的拆分逻辑
你原有的分隔符\n\r\n存在跨系统兼容问题,先统一换行符后按空行拆分记录,大文件场景开启流式处理避免内存溢出:
from("file://data/input") .convertBodyTo(String.class) // 统一替换Windows换行符,避免分隔失效 .setBody(body().replaceAll("\\r", "")) // 按空行拆分单条用户记录,开启流式处理 .split(body().tokenize("\n\n")).streaming() .to("direct:card");
第二步:自定义解析逻辑映射POJO
不需要使用KeyValue格式的反序列化,直接在路由中加处理器,按字符串键名匹配字段赋值,之后直接用Bindy的CSV序列化能力输出即可:
from("direct:card") .process(exchange -> { String singleRecord = exchange.getIn().getBody(String.class); User user = new User(); String[] fieldLines = singleRecord.split("\\n"); for (String line : fieldLines) { line = line.trim(); if (line.isEmpty()) continue; // 按第一个冒号拆分键值,兼容值中包含冒号的场景 String[] keyValue = line.split("\\s*:\\s*", 2); if (keyValue.length < 2) continue; String fieldKey = keyValue[0]; String fieldValue = keyValue[1]; // 按文本中的实际键名映射到POJO字段 switch (fieldKey) { case "Name": user.setName(fieldValue); break; case "City": user.setCity(fieldValue); break; case "Country": user.setCountry(fieldValue); break; default: // 非目标字段直接忽略 } } exchange.getIn().setBody(user); }) // 序列化输出CSV,自动生成表头 .marshal().bindy(BindyType.Csv, User.class) .to("file://data/output?fileName=users.csv");
第三步:调整User类注解适配CSV序列化
去掉原来的KeyValue相关注解,换成CSV序列化对应的注解即可:
@CsvRecord(separator = ",", generateHeaderColumns = true) public class User { @DataField(pos = 1, columnName = "Name") String name; @DataField(pos = 2, columnName = "City") String city; @DataField(pos = 3, columnName = "Country") String country; // 保留原有getter/setter方法即可 public String getName() {return name;} public void setName(String name) {this.name = name;} public String getCity() {return city;} public void setCity(String city) {this.city = city;} public String getCountry() {return country;} public void setCountry(String country) {this.country = country;} }
方案2:通用键值对解析扩展(适合字段多、不想硬写映射的场景)
如果字段数量多不想手动写switch判断,可以提前做字段名和Setter方法的映射,读取到键名时反射调用对应Setter赋值即可,本质逻辑和方案1一致,只是把硬编码映射改成配置化映射,适合字段经常调整的场景。
注意:不要为了这个场景引入重量级的第三方解析库,自定义几行代码的解析逻辑性能远高于通用格式解析库,调试也更简单。
内容的提问来源于stack exchange,提问作者Daniele Ravizza
相关产品推荐
相关产品推荐

