检查嵌套JSON

时间:2015-06-25 07:14:16

标签: java json

我遇到了需要检查嵌套JSON对象中是否存在密钥的情况。通过嵌套的JSON对象,我在父JSON对象中有一个JSON对象作为其键之一的值。所以我需要检查这个键是否存在于整个JSON对象中。我将以下数据作为String对象获取。我知道我可以解析这个String对象来获取JSON对象。

{
"claim_loss_type_cd": "TEL",
"claim_type": "002",
"claim_reason": "001",
"policy_number": "1234kk3366ff664",
"info": {
    "ApplicationContext": {
        "country": "US"
    }
  }
}

我使用containsKey()方法检查主JSON对象中的密钥是否存在并且它有效。但是要检查任何内部JSON对象,例如" info"我需要再次将Object解析为JSON对象,然后再次检查密钥。

        String jsonString = "My JSON String here";
        JSONObject finalResponse = new JSONObject(jsonString);
        finalResponse.containsKey("country"); // will return false
        JSONObject intermediateResponse = (JSONObject)finalResponse.get("info");
        intermediateResponse.containsKey("country"); // will return true

有没有更好的方法,任何可以在任何内部JSON对象内部检查的API或方法,而无需解析内部JSON对象。我正在为Websphere Application Server使用com.ibm.json.java.JSONObject.JSONObject()本机IBM库,而我正在使用其他JSON解析器。

考虑上面的JSON,例如" claim_type"是父JSON对象中的键,但" info"本身就是一个JSON对象。 所以我需要做的是检查一个密钥是否存在于完整的JSON中,无论是在父级还是其任何子JSON对象中,如key" country"这里是示例。

修改

感谢@chsdk,我找到了解决方案。但是,如果有其他人使用其他API来解决任何问题,请回复,因为以下解决方案正在考虑递归和&可能有很大的空间/时间复杂性。

public static boolean checkKey(JSONObject object, String searchedKey) {
    boolean exists = object.containsKey(searchedKey);
    if(!exists) {      
         Set<String> keys = object.keySet();
         for(String key : keys){
             if ( object.get(key) instanceof JSONObject ) {
                    exists = checkKey((JSONObject)object.get(key), searchedKey);
            }
         }
    }
    return exists;
}

4 个答案:

答案 0 :(得分:3)

您可以使用 JSONObject 来解析您的json并使用其 has(String key) 方法来检查密钥是否存在于这个Json中:

 String str="{\"claim_loss_type_cd\": \"TEL\",\"claim_type\":\"002\",\"claim_reason\": \"001\",\"policy_number\":\"1234kk3366ff664\",\"info\": {\"ApplicationContext\":{\"country\": \"US\"}}}";
 Object obj=JSONValue.parse(str);
 JSONObject json = (JSONObject) obj;
 //Then use has method to check if this key exists or not
 System.out.println(json.has("claim_type")); //Returns true

修改

或者更好的是,您只需检查JSON字符串是否包含此键值,例如使用indexOf()方法:

String str="{\"claim_loss_type_cd\": \"TEL\",\"claim_type\":\"002\",\"claim_reason\": \"001\",\"policy_number\":\"1234kk3366ff664\",\"info\": {\"ApplicationContext\":{\"country\": \"US\"}}}";
System.out.println(str.indexOf("claim_type")>-1); //Returns true

编辑2:

看看这个方法,它遍历嵌套对象以检查密钥是否存在。

public boolean keyExists(JSONObject  object, String searchedKey) {
    boolean exists = object.has(searchedKey);
    if(!exists) {      
        Iterator<?> keys = object.keys();
        while( keys.hasNext() ) {
            String key = (String)keys.next();
            if ( object.get(key) instanceof JSONObject ) {
                    exists = keyExists(object.get(key), searchedKey);
            }
        }
    }
    return exists;
}

Object obj=JSONValue.parse(str);
JSONObject json = (JSONObject) obj;
System.out.println(keyExists(json, "country")); //Returns true

答案 1 :(得分:0)

正确投射类型的现成方法:

/**
 * JSONObject contains the given key. Search is also done in nested 
 * objects recursively.
 *
 * @param json JSONObject to serach in.
 * @param key Key name to search for.
 * @return Key is found.
 */
public static boolean hasKey(
  JSONObject json,
  String key) {

  boolean exists = json.has(key);
  Iterator<?> keys;
  String nextKey;

  if (!exists) {

    keys = json.keys();

    while (keys.hasNext()) {
      nextKey = (String) keys.next();

      try {
        if (json.get(nextKey) instanceof JSONObject) {
          exists =
            hasKey(
              json.getJSONObject(nextKey),
              key);
        }
      } catch (JSONException e) {
        e.printStackTrace();
      }
    }
  }

  return exists;
}

答案 2 :(得分:0)

这两个解决方案建议以递归方式迭代JsonObject,它们有一个小错误:当它们最终找到搜索到的密钥时,它们不会破坏迭代。所以你必须打破while循环,否则循环将继续,如果有下一个键,它将检查此键,依此类推。 搜索“country”-key的代码示例仅起作用,因为“country”巧合地是其JsonObject中的最后一个键。

示例:

 /* ... */
    while (keys.hasNext()) {
          nextKey = (String) keys.next();

          try {
            if (json.get(nextKey) instanceof JSONObject) {
              exists = hasKey(json.getJSONObject(nextKey), key);

              if(exists){
                  break;
              }

            }
          } catch (JSONException e) {
            e.printStackTrace();
          }
        }
    /* ... */

答案 3 :(得分:0)

我遇到了类似的问题需要克服,将 JSON 转换为 Map 并收集键值对并迭代它们以获得我需要的值(它一次又一次地调用相同的方法,但感觉比递归编程更好。希望它有帮助).

public static void jsonToMap(String t) throws JSONException {

    Map<String,String> map = new HashMap<>();
    getJsonObjectMap(t).entrySet()
        .stream()
        .filter(s->s.getKey().equals("info"))
        .forEach(u -> {
            try {
                getJsonObjectMap(u.getValue()).forEach(map::put);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        });
        
    map.entrySet().forEach(System.out::println);

}

private static Map<String,String> getJsonObjectMap(String t) throws JSONException {

    HashMap<String,String>  map = new HashMap<>();
    JSONObject jObject = new JSONObject(t);
    Iterator<?> keys = jObject.keys();
    while( keys.hasNext() ){
        String key = (String)keys.next();
        String value = jObject.getString(key);
        map.put(key, value);
    }
    return map;
}