2013-11-04 66 views
38

我想解析Java中的JSON字符串並找到鍵值對,以便我可以確定JSON對象的近似結構,因爲JSON字符串的對象結構未知。在Java中解析JSON而不知道JSON格式

例如,一個執行可能有一個JSON字符串是這樣的:

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

而另一個是這樣的:

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

我將如何通過不同的JSON元素週期,並確定鍵和他們的價值?我看着jackson-coreJsonParser。我看到如何獲取下一個「標記」並確定它是什麼類型的標記(即字段名稱,值,數組開始等),但是,我不知道如何獲取實際標記的值。

例如:

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

是否有jackson類或穿過JSON元件產生一個樹,或允許一個週期和在獲得實際的鍵名的一些其他的庫(gsonsimple-json)除了值?

+0

那麼,簡單的部分就是解析爲地圖和列表 - 這是每個合理的JSON解析器都可以做得很好的東西。當然,更難的部分是弄清楚數據的含義,如果每次都完全不同。 –

+1

(如果您還沒有這樣做,請訪問json.org並瞭解基本的JSON語法。所有值都是數字,布爾值,字符串,對象(映射),數組或空值 - 沒有更復雜的了。 –

+0

感謝您的建議和鏈接。我對JSON非常熟悉;只是不解析沒有註釋和/或立即過渡到現有的pojo結構。 – whyceewhite

回答

50

Jacksons built-in tree model feature看看。

您的代碼將是:

public void parse(String json) { 
     JsonFactory factory = new JsonFactory(); 

     ObjectMapper mapper = new ObjectMapper(factory); 
     JsonNode rootNode = mapper.readTree(json); 

     Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.fields(); 
     while (fieldsIterator.hasNext()) { 

      Map.Entry<String,JsonNode> field = fieldsIterator.next(); 
      System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue()); 
     } 
} 
+7

是的,這是我需要的。謝謝。對於閱讀此內容的其他人,我發現[此答案](http://stackoverflow.com/a/13926850/2333544)也可能有所幫助。 – whyceewhite

+0

在任何其他語言中,這隻會被稱爲「解析的JSON」,並且會是您經常使用的東西。 –

+0

嘗試捕捉周圍的#readTree調用自ti引發檢查JsonProcessingException – Chepech

12

如果一個不同的庫是罰款,你可以嘗試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... 
} 
+1

很高興知道,因爲我不僅限於傑克遜圖書館。謝謝。 – whyceewhite

+0

這是真正的解決方案:簡單而優雅。謝謝。 –

+1

object.getName()不是'_value的成員getNames不是 \t的成員org.json.JSONObject_' –

0

你會得到滿意的從傑克遜Map

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

或者可能是JsonNode

JsonNode jsonNode = objectMapper.readTree(String jsonString) 
0

要獲得JSON迅速進入Java對象(地圖),然後可以 '鑽',並與工作,你可以使用JSON-IO(https://github.com/jdereg/json-io)。這個庫會讓你閱讀一個JSON字符串,並取回一個'Map of Maps'表示。

如果您的JVM中有相應的Java類,那麼您可以讀入JSON並將其直接解析爲Java類的實例。

JsonReader.jsonToMaps(String json) 

其中json是包含要讀取的JSON的字符串。返回值是一個Map,其中鍵將包含JSON字段,並且這些值將包含關聯的值。

JsonReader.jsonToJava(String json) 

將讀取相同的JSON字符串,並且返回值將被序列化爲JSON的Java實例。如果你有被寫了

JsonWriter.objectToJson(MyClass foo). 
+0

這不會提供問題的答案 - *在Java中解析JSON而不知道JSON格式*。假設OP的* JVM中有* Java類轉換爲JSON意味着他知道這種格式,並且格式不像他所要求的那麼有活力。 – shadyyx

+0

json-io並不認爲你的JVM中有類。 JsonReader.jsonToMaps()將讀取任何JSON。結果是Map of Maps表示。這張地圖的表示圖可以用這張地圖的地圖格式來操作,甚至可以重新寫回。 –

5

是找到使用GSON庫未知的JSON對象解析下面的代碼在JVM中的類使用這個API。

public class JsonParsing { 
static JsonParser parser = new JsonParser(); 

public static HashMap<String, Object> createHashMapFromJsonString(String json) { 

    JsonObject object = (JsonObject) parser.parse(json); 
    Set<Map.Entry<String, JsonElement>> set = object.entrySet(); 
    Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator(); 
    HashMap<String, Object> map = new HashMap<String, Object>(); 

    while (iterator.hasNext()) { 

     Map.Entry<String, JsonElement> 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<HashMap<String, Object>> 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; 
} 
} 
+0

正是我看這個超級作品 –

2

未知格式的JSONHashMap

JSON而閱讀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 <java.util.Map.Entry<String, com.google.gson.JsonElement>> keys = object.entrySet(); 
     if (keys.isEmpty()) { 
      System.out.println("Empty JSON Object"); 
     }else { 
      Map<String, Object> 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<String, Object> json_UnKnown_Format(Set <java.util.Map.Entry<String, com.google.gson.JsonElement>> keys){ 
    Map<String, Object> jsonMap = new HashMap<String, Object>(); 
    for (Entry<String, JsonElement> 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<Object> array2List = new ArrayList<Object>(); 
      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 <java.util.Map.Entry<String, com.google.gson.JsonElement>> 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<String, Integer> sortedTree = new TreeMap<String, Integer>(); 
     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(); 
    } 

} 
0

這裏有一個例子我寫了節目我是如何解析JSON和混亂每個數字內它:

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<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields(); 
      while (fieldsIterator.hasNext()) { 
       Map.Entry<String, JsonNode> 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<String, JsonNode> 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; 
    } 
}