我有一个文件作为输入,其中包含一个json数组:
[ {
...,
...
},
{
...,
...
},
{
...,
...
}
]
我想在不破坏spring批处理原则的情况下阅读它(与FlatFileReader或XmlReader的方式相同)
我没有找到任何方法来实现已经在春季批量实施的读者。
实施此阅读器的最佳方法是什么?
先谢谢
答案 0 :(得分:1)
假设你想要建模StaxEventItemReader
,你想要将JSON数组的每个项目作为Spring Batch中的项目进行建模,这就是我推荐的内容:
RecordSeparatorPolicy
- 您需要实施自己的RecordSepartorPolicy
,表明您是否已完成阅读完整项目。您还可以使用RecordSeparatoerPolicy#postProcess
清除您需要处理的开头和结尾[]
以及逗号分隔符。 LineTokenizer
- 然后您想要创建自己的LineTokenzier
来解析JSON。我今天正在为一个项目工作,所以你可以使用该代码作为开始(考虑它未经测试):
public class JsonLineTokenizer implements LineTokenizer {
@Override
public FieldSet tokenize(String line) {
List<String> tokens = new ArrayList<>();
try {
HashMap<String,Object> result =
new ObjectMapper().readValue(line, HashMap.class);
tokens.add((String) result.get("field1"));
tokens.add((String) result.get("field2")));
} catch (IOException e) {
throw new RuntimeException("Unable to parse json: " + line);
}
return new DefaultFieldSet(tokens.toArray(new String[0]), {"field1", "field2"});
}
}
答案 1 :(得分:0)
这是我从您的建议和默认实现开始编写的记录分隔符策略。 我为读取记录使用内部纯字符串表示,但我发现使用codehaus jettison JSON对象解析JSON非常简单。
public class JsonRecordSeparatorPolicy extends SimpleRecordSeparatorPolicy {
/**
* True if the line can be parsed to a JSON object.
*
* @see RecordSeparatorPolicy#isEndOfRecord(String)
*/
@Override
public boolean isEndOfRecord(String line) {
return StringUtils.countOccurrencesOf(line, "{") == StringUtils.countOccurrencesOf(line, "}")
&& (line.trim().endsWith("}") || line.trim().endsWith(",") || line.trim().endsWith("]") );
}
@Override
public String postProcess(String record) {
if(record.startsWith("[")) record = record.substring(1);
if(record.endsWith("]")) record = record.substring(0, record.length()-1);
if(record.endsWith(",")) record = record.substring(0, record.length()-1);
return super.postProcess(record);
}
}