Spring Batch读取复杂JSON:如何忽略单独成行的末尾]?
解决FlatFileItemReader读取JSON数组时忽略单独结尾"]"的问题
看起来你之前的ComplexJsonRecordSeparatorPolicy是靠固定行号来判断结尾的],但当JSON数组元素数量变化、]单独占一行时,这种固定行号的逻辑就失效了。正确的思路应该是基于内容而非行号来识别有效记录,同时自动跳过开头的[、结尾的]以及空白行。
自定义RecordSeparatorPolicy的正确实现
我们可以继承DefaultRecordSeparatorPolicy,重写核心方法来实现适配JSON数组的分隔逻辑:
import org.springframework.batch.item.file.separator.DefaultRecordSeparatorPolicy; public class ComplexJsonRecordSeparatorPolicy extends DefaultRecordSeparatorPolicy { @Override public boolean isEndOfRecord(String line) { String trimmedLine = line.trim(); // 跳过开头的[、结尾的]以及空白行,这些不属于有效记录 if (trimmedLine.equals("[") || trimmedLine.equals("]") || trimmedLine.isEmpty()) { return false; } // 判断当前行是否是完整JSON对象的结尾:兼容带逗号的中间对象和不带逗号的最后一个对象 return trimmedLine.endsWith("},") || trimmedLine.endsWith("}"); } @Override public String postProcess(String record) { // 清理记录格式:去掉前后空白和末尾多余的逗号,保证JSON可单独解析 String trimmedRecord = record.trim(); if (trimmedRecord.endsWith(",")) { return trimmedRecord.substring(0, trimmedRecord.length() - 1); } return trimmedRecord; } }
配置FlatFileItemReader使用该策略
在你的Reader配置中,指定这个自定义分隔策略即可:
@Bean public FlatFileItemReader<Person> jsonPersonReader() { FlatFileItemReader<Person> reader = new FlatFileItemReader<>(); reader.setResource(new ClassPathResource("your-json-file.json")); // 用Jackson将JSON行映射为实体类(替换成你自己的实体类型) reader.setLineMapper((line, lineNumber) -> { ObjectMapper objectMapper = new ObjectMapper(); return objectMapper.readValue(line, Person.class); }); // 绑定自定义分隔策略 reader.setRecordSeparatorPolicy(new ComplexJsonRecordSeparatorPolicy()); return reader; }
这个方案的优势
- 不依赖固定行号:完全基于行内容判断,不管
]在第几行都会被跳过,适配任何长度的JSON数组。 - 自动过滤无效行:开头的
[、空白行都会被忽略,只处理真正的JSON对象行。 - 兼容两种对象格式:不管是中间带逗号的对象(
{"firstName":"Tom", "lastName":"Cruise"},)还是最后一个不带逗号的对象({"firstName":"Liam", "lastName":"Neeson"}),都能正确识别为完整记录。 - 保证JSON格式合法:
postProcess方法会去掉末尾多余的逗号,确保每个记录都是可单独解析的合法JSON对象。
如果你的JSON对象存在跨行的情况(比如一个对象占多行),可以进一步扩展isEndOfRecord方法,通过统计{和}的数量来判断记录是否结束,不过从你的示例场景来看,单行对象的情况这个实现已经完全够用。
内容的提问来源于stack exchange,提问作者ams2705
相关产品推荐
相关产品推荐

