Analisi di JSON in Java senza conoscere il formato JSON

Sto cercando di analizzare le stringhe JSON in Java e trovare le coppie chiave-valore in modo da poter determinare la struttura approssimativa dell’object JSON poiché la struttura dell’object della stringa JSON è sconosciuta.

Ad esempio, un’esecuzione può avere una stringa JSON come questa:

{"id" : 12345, "days" : [ "Monday", "Wednesday" ], "person" : { "firstName" : "David", "lastName" : "Menoyo" } } 

E un altro come questo:

  {"url" : "http://someurl.com", "method" : "POST", "isauth" : false } 

Come posso scorrere i vari elementi JSON e determinare le chiavi e i loro valori? Ho guardato il JsonParser jackson-core . Vedo come posso prendere il prossimo “token” e determinare quale tipo di token è (cioè, nome del campo, valore, matrice di avvio, ecc), ma, non so come afferrare il valore del token effettivo.

Per esempio:

 public void parse(String json) { try { JsonFactory f = new JsonFactory(); JsonParser parser = f.createParser(json); JsonToken token = parser.nextToken(); while (token != null) { if (token.equals(JsonToken.START_ARRAY)) { logger.debug("Start Array : " + token.toString()); } else if (token.equals(JsonToken.END_ARRAY)) { logger.debug("End Array : " + token.toString()); } else if (token.equals(JsonToken.START_OBJECT)) { logger.debug("Start Object : " + token.toString()); } else if (token.equals(JsonToken.END_OBJECT)) { logger.debug("End Object : " + token.toString()); } else if (token.equals(JsonToken.FIELD_NAME)) { logger.debug("Field Name : " + token.toString()); } else if (token.equals(JsonToken.VALUE_FALSE)) { logger.debug("Value False : " + token.toString()); } else if (token.equals(JsonToken.VALUE_NULL)) { logger.debug("Value Null : " + token.toString()); } else if (token.equals(JsonToken.VALUE_NUMBER_FLOAT)) { logger.debug("Value Number Float : " + token.toString()); } else if (token.equals(JsonToken.VALUE_NUMBER_INT)) { logger.debug("Value Number Int : " + token.toString()); } else if (token.equals(JsonToken.VALUE_STRING)) { logger.debug("Value String : " + token.toString()); } else if (token.equals(JsonToken.VALUE_TRUE)) { logger.debug("Value True : " + token.toString()); } else { logger.debug("Something else : " + token.toString()); } token = parser.nextToken(); } } catch (Exception e) { logger.error("", e); } } 

Esiste una class in jackson o qualche altra libreria ( gson o simple-json ) che produce un albero, o consente a uno di scorrere gli elementi json e ottenere i nomi dei tasti effettivi oltre ai valori?

Dai un’occhiata al feature del modello ad albero integrato di Jacksons .

E il tuo codice sarà:

 public void parse(String json) { JsonFactory factory = new JsonFactory(); ObjectMapper mapper = new ObjectMapper(factory); JsonNode rootNode = mapper.readTree(json); Iterator> fieldsIterator = rootNode.fields(); while (fieldsIterator.hasNext()) { Map.Entry field = fieldsIterator.next(); System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue()); } } 

Se una libreria diversa va bene per te, puoi provare org.json :

 JSONObject object = new JSONObject(myJSONString); String[] keys = JSONObject.getNames(object); for (String key : keys) { Object value = object.get(key); // Determine type of value and do something with it... } 

Trova il seguente codice per l’analisi di Json Object sconosciuto utilizzando la libreria Gson.

 public class JsonParsing { static JsonParser parser = new JsonParser(); public static HashMap createHashMapFromJsonString(String json) { JsonObject object = (JsonObject) parser.parse(json); Set> set = object.entrySet(); Iterator> iterator = set.iterator(); HashMap map = new HashMap(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); String key = entry.getKey(); JsonElement value = entry.getValue(); if (null != value) { if (!value.isJsonPrimitive()) { if (value.isJsonObject()) { map.put(key, createHashMapFromJsonString(value.toString())); } else if (value.isJsonArray() && value.toString().contains(":")) { List> list = new ArrayList<>(); JsonArray array = value.getAsJsonArray(); if (null != array) { for (JsonElement element : array) { list.add(createHashMapFromJsonString(element.toString())); } map.put(key, list); } } else if (value.isJsonArray() && !value.toString().contains(":")) { map.put(key, value.getAsJsonArray()); } } else { map.put(key, value.getAsString()); } } } return map; } } 

JSON di formato sconosciuto per HashMap

scrivere JSON e leggere Json

 public static JsonParser parser = new JsonParser(); public static void main(String args[]) { writeJson("JsonFile.json"); readgson("JsonFile.json"); } public static void readgson(String file) { try { System.out.println( "Reading JSON file from Java program" ); FileReader fileReader = new FileReader( file ); com.google.gson.JsonObject object = (JsonObject) parser.parse( fileReader ); Set > keys = object.entrySet(); if ( keys.isEmpty() ) { System.out.println( "Empty JSON Object" ); }else { Map map = json_UnKnown_Format( keys ); System.out.println("Json 2 Map : "+map); } } catch (IOException ex) { System.out.println("Input File Does not Exists."); } } public static Map json_UnKnown_Format( Set > keys ){ Map jsonMap = new HashMap(); for (Entry entry : keys) { String keyEntry = entry.getKey(); System.out.println(keyEntry + " : "); JsonElement valuesEntry = entry.getValue(); if (valuesEntry.isJsonNull()) { System.out.println(valuesEntry); jsonMap.put(keyEntry, valuesEntry); }else if (valuesEntry.isJsonPrimitive()) { System.out.println("P - "+valuesEntry); jsonMap.put(keyEntry, valuesEntry); }else if (valuesEntry.isJsonArray()) { JsonArray array = valuesEntry.getAsJsonArray(); List array2List = new ArrayList(); for (JsonElement jsonElements : array) { System.out.println("A - "+jsonElements); array2List.add(jsonElements); } jsonMap.put(keyEntry, array2List); }else if (valuesEntry.isJsonObject()) { com.google.gson.JsonObject obj = (JsonObject) parser.parse(valuesEntry.toString()); Set > obj_key = obj.entrySet(); jsonMap.put(keyEntry, json_UnKnown_Format(obj_key)); } } return jsonMap; } @SuppressWarnings("unchecked") public static void writeJson( String file ) { JSONObject json = new JSONObject(); json.put("Key1", "Value"); json.put("Key2", 777); // Converts to "777" json.put("Key3", null); json.put("Key4", false); JSONArray jsonArray = new JSONArray(); jsonArray.put("Array-Value1"); jsonArray.put(10); jsonArray.put("Array-Value2"); json.put("Array : ", jsonArray); // "Array":["Array-Value1", 10,"Array-Value2"] JSONObject jsonObj = new JSONObject(); jsonObj.put("Obj-Key1", 20); jsonObj.put("Obj-Key2", "Value2"); jsonObj.put(4, "Value2"); // Converts to "4" json.put("InnerObject", jsonObj); JSONObject jsonObjArray = new JSONObject(); JSONArray objArray = new JSONArray(); objArray.put("Obj-Array1"); objArray.put(0, "Obj-Array3"); jsonObjArray.put("ObjectArray", objArray); json.put("InnerObjectArray", jsonObjArray); Map sortedTree = new TreeMap(); sortedTree.put("Sorted1", 10); sortedTree.put("Sorted2", 103); sortedTree.put("Sorted3", 14); json.put("TreeMap", sortedTree); try { System.out.println("Writting JSON into file ..."); System.out.println(json); FileWriter jsonFileWriter = new FileWriter(file); jsonFileWriter.write(json.toJSONString()); jsonFileWriter.flush(); jsonFileWriter.close(); System.out.println("Done"); } catch (IOException e) { e.printStackTrace(); } } 

Saresti soddisfatto con una Map di Jackson?

 ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(jsonString, new TypeReference>(){}); 

O forse un JsonNode ?

 JsonNode jsonNode = objectMapper.readTree(String jsonString) 

Per ottenere rapidamente JSON in oggetti Java (Maps) che è ansible quindi eseguire “drill” e lavorare, è ansible utilizzare json-io ( https://github.com/jdereg/json-io ). Questa libreria ti consente di leggere in una stringa JSON e di recuperare una rappresentazione di “Mappa di Maps”.

Se si hanno le classi Java corrispondenti nella JVM, è ansible leggere il JSON e lo analizzerà direttamente nelle istanze delle classi Java.

 JsonReader.jsonToMaps(String json) 

dove json è la stringa contenente il JSON da leggere. Il valore restituito è una mappa in cui le chiavi conterranno i campi JSON e i valori conterranno i valori associati.

 JsonReader.jsonToJava(String json) 

leggerà la stessa stringa JSON e il valore restituito sarà l’istanza Java serializzata nel JSON. Usa questa API se hai le classi nella tua JVM che sono state scritte da

 JsonWriter.objectToJson(MyClass foo). 

Ecco un esempio che ho scritto mostra come analizzo un json e pasticcio ogni numero al suo interno:

 public class JsonParser { public static Object parseAndMess(Object object) throws IOException { String json = JsonUtil.toJson(object); JsonNode jsonNode = parseAndMess(json); if(null != jsonNode) return JsonUtil.toObject(jsonNode, object.getClass()); return null; } public static JsonNode parseAndMess(String json) throws IOException { JsonNode rootNode = parse(json); return mess(rootNode, new Random()); } private static JsonNode parse(String json) throws IOException { JsonFactory factory = new JsonFactory(); ObjectMapper mapper = new ObjectMapper(factory); JsonNode rootNode = mapper.readTree(json); return rootNode; } private static JsonNode mess(JsonNode rootNode, Random rand) throws IOException { if (rootNode instanceof ObjectNode) { Iterator> fieldsIterator = rootNode.fields(); while (fieldsIterator.hasNext()) { Map.Entry field = fieldsIterator.next(); replaceObjectNode((ObjectNode) rootNode, field, rand); } } else if (rootNode instanceof ArrayNode) { ArrayNode arrayNode = ((ArrayNode) rootNode); replaceArrayNode(arrayNode, rand); } return rootNode; } private static void replaceObjectNode(ObjectNode rootNode, Map.Entry field, Random rand) throws IOException { JsonNode childNode = field.getValue(); if (childNode instanceof IntNode) { (rootNode).put(field.getKey(), rand.nextInt(1000)); } else if (childNode instanceof LongNode) { (rootNode).put(field.getKey(), rand.nextInt(1000000)); } else if (childNode instanceof FloatNode) { (rootNode).put(field.getKey(), format(rand.nextFloat())); } else if (childNode instanceof DoubleNode) { (rootNode).put(field.getKey(), format(rand.nextFloat())); } else { mess(childNode, rand); } } private static void replaceArrayNode(ArrayNode arrayNode, Random rand) throws IOException { int arrayLength = arrayNode.size(); if(arrayLength == 0) return; if (arrayNode.get(0) instanceof IntNode) { for (int i = 0; i < arrayLength; i++) { arrayNode.set(i, new IntNode(rand.nextInt(10000))); } } else if (arrayNode.get(0) instanceof LongNode) { arrayNode.removeAll(); for (int i = 0; i < arrayLength; i++) { arrayNode.add(rand.nextInt(1000000)); } } else if (arrayNode.get(0) instanceof FloatNode) { arrayNode.removeAll(); for (int i = 0; i < arrayLength; i++) { arrayNode.add(format(rand.nextFloat())); } } else if (arrayNode.get(0) instanceof DoubleNode) { arrayNode.removeAll(); for (int i = 0; i < arrayLength; i++) { arrayNode.add(format(rand.nextFloat())); } } else { for (int i = 0; i < arrayLength; i++) { mess(arrayNode.get(i), rand); } } } public static void print(JsonNode rootNode) throws IOException { System.out.println(rootNode.toString()); } private static double format(float a) { return Math.round(a * 10000.0) / 100.0; } }