Java 检查嵌套JSON中是否存在密钥

Java 检查嵌套JSON中是否存在密钥,java,json,Java,Json,我陷入了需要检查嵌套JSON对象中是否存在键的情况。通过嵌套JSON对象,我在父JSON对象中有一个JSON对象作为其一个键的值。所以我需要检查这个键是否存在于整个JSON对象中。我将以下数据作为字符串对象获取。我知道我可以解析这个字符串对象来获得JSON对象 { "claim_loss_type_cd": "TEL", "claim_type": "002", "claim_reason": "001", "policy_number": "1234kk3366ff664", "info":

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

{
"claim_loss_type_cd": "TEL",
"claim_type": "002",
"claim_reason": "001",
"policy_number": "1234kk3366ff664",
"info": {
    "ApplicationContext": {
        "country": "US"
    }
  }
}
我使用了
containsKey()
方法来检查主JSON对象中是否存在密钥,它可以正常工作。但要检查任何内部JSON对象,如“info”,我需要再次将
对象
解析为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
那么有没有更好的方法,任何API或方法可以检查任何内部JSON对象,而无需解析内部JSON对象。我正在使用Websphere Application Server的本机ibm库
com.ibm.json.java.JSONObject.JSONObject()

考虑到上面的JSON,比如“claim_type”是父JSON对象中的键,但“info”本身是JSON对象。 所以我需要做的是检查一个键是否存在于完整的JSON中,无论是在父JSON对象中,还是在它的任何子JSON对象中,如示例中的键“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;
}
公共静态布尔校验键(JSONObject对象,字符串searchedKey){
布尔存在=object.containsKey(searchedKey);
如果(!存在){
Set keys=object.keySet();
用于(字符串键:键){
if(object.get(key)instanceof JSONObject){
exists=checkKey((JSONObject)object.get(key),searchedKey);
}
}
}
回报存在;
}
您可以使用解析json,并使用其方法检查此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
公共布尔键存在(JSONObject对象,字符串searchedKey){
boolean exists=object.has(searchedKey);
如果(!存在){
迭代器键=object.keys();
while(keys.hasNext()){
字符串键=(字符串)键。下一步();
if(object.get(key)instanceof JSONObject){
exists=keyExists(object.get(key),searchedKey);
}
}
}
回报存在;
}
objectobj=JSONValue.parse(str);
JSONObject json=(JSONObject)obj;
System.out.println(keyExists(json,“国家”)//返回true

一种具有正确类型转换的现成方法:

/**
 * 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;
}
/**
*JSONObject包含给定的键。搜索也会在嵌套中完成
*对象递归。
*
*@param json JSONObject到serach中。
*@param key要搜索的密钥名。
*找到了@return键。
*/
公共静态布尔hasKey(
JSONObject json,
字符串键){
boolean exists=json.has(键);
迭代器键;
字符串nextKey;
如果(!存在){
keys=json.keys();
while(keys.hasNext()){
nextKey=(字符串)keys.next();
试一试{
if(json.get(nextKey)instanceof JSONObject){
存在=
哈斯基(
getJSONObject(nextKey),
键);
}
}捕获(JSONException e){
e、 printStackTrace();
}
}
}
回报存在;
}

这两种建议递归迭代JsonObject的解决方案都有一个小缺陷:它们在最终找到搜索的键时不会中断迭代。因此,您必须中断while循环,否则循环将继续,如果有下一个键,它将检查该键,依此类推。 代码示例只搜索“country”键,因为“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();
          }
        }
    /* ... */

你有没有使用过像jakson之类的JSON解析器?伙计们,JSON(这个词)不是代码,不要将它格式化为代码块。@TimCastelijns有人建议我将JSON作为代码,所以我接受了编辑的建议如果你将JSON作为原始字符串,可以对照regex
“country”进行检查吗\s*:
?@MuhammadSuleman不,我没有使用任何额外的语法分析。我已经编辑了我的问题,以获得正确的解释。我不想解析内部JSON对象。这个
has()
方法可以检查整个json
String
并且可以检查键是否存在否它不检查内部JSONObject,但是您可以从一开始就直接检查字符串中键的存在性。谢谢,但实际上我想从任何JSON方法进行检查,而不是使用Stringyes进行操作,这看起来很有希望&可能会解决需求,但是性能问题呢,将其称为方法
keyExists()
recursively递归调用它没有问题,因为您可以看到,如果键退出,它将不会从一开始就进入循环,并且它将仅通过嵌套的JSONObject进行递归调用。