我遇到了需要检查嵌套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;
}
答案 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;
}