2014-08-29 89 views
1

我有一个文件包含JSON数组输入:的Json与Spring Batch的阵列读取文件

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

我想没有打破春季批次principales(用同样的方式FlatFileReader或XmlReader中读取它)

我没有找到任何方法来完成已经在spring-batch中实现的读取器。

什么是最好的方式来实现这个读者?

由于提前

回答

1

假设你想在你想要阅读的JSON数组作为Spring Batch的一个项目的每个项目StaxEventItemReader模型,这里是我建议:

  • 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"}); 
        } 
    } 
    
+0

感谢您的答复,该RecordSeparatorPolicy将难以实现,因为我没有一个简单的JSON格式的项目,而是一个复杂的,可以包含以及JSON数组,任何想法 – Nabil 2014-08-30 00:06:22

+0

我可以看到唯一的复杂性是'RecordSeparatorPolicy'需要能够忽略包裹整个文档的[]和每个项目之间的逗号。我错过了什么吗? – 2014-09-01 16:56:58

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

}