先日書いた「Big JSON を読み込む JsonReader」、
より実践的なサンプルを書いてみる。
JSON素材
{ "category": "JsonReader テスト", "filename": "sample.json", "itemlist":[ { "name": "A", "flag": true, "time": "2020/06/05 22:14:25" }, { "name": "B", "flag": false, "time": "2020/06/05 10:08:17" }, { "name": "C", "flag": true, "time": "2020/06/04 08:54:09" } ], "footer": "ウラン", "count": 3 }
この itemlist 配列の1つを表す class
public class Item{ public String name; public boolean flag; public LocalDateTime time; @Override public String toString(){ return name+" "+" "+flag+" \t"+time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } }
解析実行
try(JsonReader reader = new JsonReader(new InputStreamReader( new FileInputStream(jsonFilePath), StandardCharsets.UTF_8))) { // itemlist 配列の Item を読込む GSON Gson gson = new GsonBuilder().serializeNulls() .registerTypeAdapter(LocalDateTime.class, LocalDateTimeAdapter.of("yyyy/MM/dd HH:mm:ss")) .create(); // itemlist 配列内で、true boolean itemParseRequest = false; // itemlist ARRAY 内の OBJECT の PATH Pattern targetptn = Pattern.compile("^\\$\\.itemlist\\[\\d+\\]$"); while((reader.hasNext() || reader.peek().equals(JsonToken.END_ARRAY) || reader.peek().equals(JsonToken.END_OBJECT) ) && !reader.peek().equals(JsonToken.END_DOCUMENT) ){ JsonToken token = reader.peek(); StringBuilder sb = new StringBuilder(); sb.append(token); String str; if (token.equals(JsonToken.BEGIN_ARRAY)){ reader.beginArray(); if (targetptn.matcher(reader.getPath()).matches()){ itemParseRequest = true; } }else if(token.equals(JsonToken.END_ARRAY)){ reader.endArray(); if (itemParseRequest) itemParseRequest = false; }else if(token.equals(JsonToken.BEGIN_OBJECT)){ if (itemParseRequest) { // 配列内、1個の Item 読込み Item item = gson.fromJson(reader, new TypeToken<Item>(){}.getType()); System.out.println("### "+item); }else{ reader.beginObject(); } }else if(token.equals(JsonToken.END_OBJECT)){ reader.endObject(); }else if(token.equals(JsonToken.NAME)){ reader.nextName(); }else if(token.equals(JsonToken.STRING)){ str = reader.nextString(); sb.append(":"+reader.getPath()+" = "); sb.append(str); }else if(token.equals(JsonToken.NUMBER)){ long l = reader.nextLong(); sb.append(":"+reader.getPath()+" = "); sb.append(l); }else if(token.equals(JsonToken.BOOLEAN)){ Boolean b = reader.nextBoolean(); sb.append(":"+reader.getPath()+" = "); sb.append(b); }else if(token.equals(JsonToken.NULL)){ reader.nextNull(); sb.append(":"+reader.getPath()+" = "); sb.append("NULL"); } /*** test ***/ if (!token.equals(JsonToken.BEGIN_OBJECT) && !token.equals(JsonToken.END_OBJECT) && !token.equals(JsonToken.NAME)){ System.out.println(sb.toString()); } /*************/ } }catch(IOException e){ e.printStackTrace(); }
テスト結果
STRING:$.category = JsonReader テスト STRING:$.filename = sample.json BEGIN_ARRAY ### A true 2020-06-05 22:14:25 ### B false 2020-06-05 10:08:17 ### C true 2020-06-04 08:54:09 END_ARRAY STRING:$.footer = ウラン NUMBER:$.count = 3