を書いたが、日付時刻は、LocalDate LocalDateTime で読み取りたいという要求に応えるために
以下のようにする。
import java.io.IOException; import java.io.InputStream; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.function.BiConsumer; import java.util.regex.Pattern; import java.util.stream.Stream; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeType; /** * JsonNodeParse */ public class JsonNodeParse{ private ObjectMapper mapper; private Map<String, DateHandle> dpMap; public JsonNodeParse() { dpMap = new HashMap<>(); mapper = new ObjectMapper(); } public JsonNodeParse addDateDeserilaize(Pattern ptn, DateTimeFormatter formatter) { dpMap.put(ptn.pattern(), new DateHandle(DateType.DATE, ptn, formatter)); return this; } public JsonNodeParse addDatetimeDeserilaize(Pattern ptn, DateTimeFormatter formatter) { dpMap.put(ptn.pattern(), new DateHandle(DateType.DATETIME, ptn, formatter)); return this; } public JsonNodeParse addTimeDeserilaize(Pattern ptn, DateTimeFormatter formatter) { dpMap.put(ptn.pattern(), new DateHandle(DateType.TIME, ptn, formatter)); return this; } enum DateType{ DATE, DATETIME, TIME } class DateHandle{ public DateType type; public Pattern ptn; public DateTimeFormatter formatter; public DateHandle(DateType type, Pattern ptn, DateTimeFormatter formatter) { this.type = type; this.ptn = ptn; this.formatter = formatter; } } public void readJson(String jsontxt, BiConsumer<String, Object> con){ try{ parseJson(mapper.readTree(jsontxt), "", con); }catch (JsonProcessingException e){ throw new RuntimeException(e); } } public void readJson(InputStream in, BiConsumer<String, Object> con){ try{ parseJson(mapper.readTree(in), "", con); }catch (JsonProcessingException e){ throw new RuntimeException(e); }catch(IOException e){ throw new RuntimeException(e); } } private void parseJson(JsonNode node, String path, BiConsumer<String, Object> con){ if (node.getNodeType().equals(JsonNodeType.OBJECT)) { for(Iterator<Entry<String, JsonNode>> it=node.fields(); it.hasNext();) { Entry<String, JsonNode> entry = it.next(); parseJson(entry.getValue(), path + "." + entry.getKey(), con); } }else if(node.getNodeType().equals(JsonNodeType.ARRAY)){ if (node.size() > 0){ int x=0; for(Iterator<JsonNode> it=node.iterator(); it.hasNext();x++){ parseJson(it.next(), path + "[" + x + "]", con); } }else{ con.accept(path.substring(1), new ArrayList<Object>()); } }else if(node.getNodeType().equals(JsonNodeType.NULL)){ con.accept(path.substring(1), null); }else if(node.getNodeType().equals(JsonNodeType.NUMBER)){ if (node.isDouble()){ con.accept(path.substring(1), node.asDouble()); }else if(node.isLong()){ con.accept(path.substring(1), node.asLong()); }else{ con.accept(path.substring(1), node.asInt()); } }else if(node.getNodeType().equals(JsonNodeType.BOOLEAN)){ con.accept(path.substring(1), node.asBoolean()); }else if(node.getNodeType().equals(JsonNodeType.STRING)){ String p = path.substring(1); dpMap.values().stream().filter(e->e.ptn.matcher(p).find()).findFirst() .<Runnable>map(e->()->{ try{ switch(e.type){ case DATE: con.accept(p, LocalDate.parse(node.asText(), e.formatter)); break; case DATETIME: con.accept(p, LocalDateTime.parse(node.asText(), e.formatter)); break; case TIME: con.accept(p, LocalTime.parse(node.asText(), e.formatter)); break; } }catch(DateTimeParseException x){ con.accept(p, node.asText()); } }).orElse(()->{ con.accept(p, node.asText()); }).run(); } } public Stream<Entry<String, Object>> jsonStream(String jsontxt){ Stream.Builder<Entry<String, Object>> builder = Stream.builder(); ObjectMapper mapper = new ObjectMapper(); try{ parseJson(mapper.readTree(jsontxt), "", builder); }catch (JsonProcessingException e){ throw new RuntimeException(e); } return builder.build(); } public Stream<Entry<String, Object>> jsonStream(InputStream in){ Stream.Builder<Entry<String, Object>> builder = Stream.builder(); ObjectMapper mapper = new ObjectMapper(); try{ parseJson(mapper.readTree(in), "", builder); }catch (JsonProcessingException e){ throw new RuntimeException(e); }catch(IOException e){ throw new RuntimeException(e); } return builder.build(); } private void parseJson(JsonNode node, String path, Stream.Builder<Entry<String, Object>> builder){ if (node.getNodeType().equals(JsonNodeType.OBJECT)) { for(Iterator<Entry<String, JsonNode>> it=node.fields(); it.hasNext();) { Entry<String, JsonNode> entry = it.next(); parseJson(entry.getValue(), path + "." + entry.getKey(), builder); } }else if(node.getNodeType().equals(JsonNodeType.ARRAY)){ if (node.size() > 0){ int x=0; for(Iterator<JsonNode> it=node.iterator(); it.hasNext();x++){ parseJson(it.next(), path + "[" + x + "]", builder); } }else{ builder.add(new SimpleEntry<String, Object>(path.substring(1), new ArrayList<Object>())); } }else if(node.getNodeType().equals(JsonNodeType.NULL)){ builder.add(new SimpleEntry<String, Object>(path.substring(1), null)); }else if(node.getNodeType().equals(JsonNodeType.NUMBER)){ if (node.isDouble()){ builder.add(new SimpleEntry<String, Object>(path.substring(1), node.asDouble())); }else if(node.isLong()){ builder.add(new SimpleEntry<String, Object>(path.substring(1), node.asLong())); }else{ builder.add(new SimpleEntry<String, Object>(path.substring(1), node.asInt())); } }else if(node.getNodeType().equals(JsonNodeType.BOOLEAN)){ builder.add(new SimpleEntry<String, Object>(path.substring(1), node.asBoolean())); }else if(node.getNodeType().equals(JsonNodeType.STRING)){ String p = path.substring(1); dpMap.values().stream().filter(e->e.ptn.matcher(p).find()).findFirst() .<Runnable>map(e->()->{ try{ switch(e.type){ case DATE: builder.add(new SimpleEntry<String, Object>(p, LocalDate.parse(node.asText(), e.formatter))); break; case DATETIME: builder.add(new SimpleEntry<String, Object>(p, LocalDateTime.parse(node.asText(), e.formatter))); break; case TIME: builder.add(new SimpleEntry<String, Object>(p, LocalTime.parse(node.asText(), e.formatter))); break; } }catch(DateTimeParseException x){ builder.add(new SimpleEntry<String, Object>(p, node.asText())); } }).orElse(()->{ builder.add(new SimpleEntry<String, Object>(p, node.asText())); }).run(); } } }
使い方
JsonNodeParse jsonNodeparse = new JsonNodeParse() .addDatetimeDeserilaize(Pattern.compile("^abc\\[\\d+\\]\\.date$"), DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")); jsonNodeparse.readJson(jsontxt, (p, o)->{ // p = JSON path // o = Object });