带弹簧批次的Json Array读取器文件

时间:2014-08-29 22:15:25

标签: spring spring-batch

我有一个文件作为输入,其中包含一个json数组:

[ {
  ...,
  ...
  },
  {
  ...,
  ...
  },
  {
  ...,
  ...
  }
]

我想在不破坏spring批处理原则的情况下阅读它(与FlatFileReader或XmlReader的方式相同)

我没有找到任何方法来实现已经在春季批量实施的读者。

实施此阅读器的最佳方法是什么?

先谢谢

2 个答案:

答案 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);
}

}