2014-08-29 88 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); 
} 

}