Java 迭代所有json对象并替换值

Java 迭代所有json对象并替换值,java,json,iterator,Java,Json,Iterator,我有以下建议: { "data":{ "attributes":{ "external-event-url":"http://example.com", "is-sponsors-enabled":"true", "is-ticketing-enabled":"true", "timezone":"UTC", "name":"${name_variable}",

我有以下建议:

{  
   "data":{  
      "attributes":{  
         "external-event-url":"http://example.com",
         "is-sponsors-enabled":"true",
         "is-ticketing-enabled":"true",
         "timezone":"UTC",
         "name":"${name_variable}",
         "ends-at":"2020-01-02T23:59:59.123456+00:00",
         "starts-at":"2020-01-01T23:59:59.123456+00:00"
      },
      "type":"event"
   }
}
我必须遍历json对象,并将变量的值替换为
${
,例如
${name\u variable}
新的json应该采用相同的格式(其中提到了变量的replace值
${}


如何迭代如此复杂的Json对象并替换变量中的值

我尝试了以下代码,但未按预期工作:

public Map<String, String> mapfillData(String jsonstr) {
    Map<String, String> map = new HashMap<String, String>();
    try {
        JSONObject jsonObject = new JSONObject(jsonstr);
        String[] keys = JSONObject.getNames(jsonObject);

        for (String key : keys) {
            try {
                if (jsonObject.get(key).toString().startsWith("${")) {
                    map.put(key, System.getProperty(jsonObject.get(key).toString()
                            .replace("${", "").replace("}", "")));
                } else {
                    if(isJSONValid(jsonObject.get(key).toString())){
                        mapfillData(jsonObject.get(key).toString());
                    }else{
                        map.put(key, jsonObject.get(key).toString());
                    }
                }

            } catch (Exception e) {

            }
        }
    } catch (JSONException e) {
        System.err.printf(jsonstr + " is not valid Json", e);
    }
    return map;
}

您的问题是,当您尝试递归处理JSON时,在每个递归级别,您都在处理不同的JSON文档,并将数据写入不同的
映射

您的函数获取一个字符串,然后将其解析为一个
JSONObject
。您创建一个
Map
来保存一些数据。第一次通过
mapfillData
,您只会找到一个键,
data
。然后,假设
if
逻辑工作正常(我没有尝试运行它),您将把
数据的内容
呈现为另一个字符串,并递归调用
mapfillData

现在您进入了对
mapfillData
的第二次调用,并创建了另一个
Map
。这次通过查找
attributes
并第三次调用
mapfillData
。在第三次调用中,您找到一些变量,并在将值写入
Map
时替换它们。在函数末尾,您可以重新调用urn
Map
,但是调用者(第二次调用
mapfillData
)不会对返回的
Map
执行任何操作,并且您的所有数据都将丢失

我想:

  • 解析JSON一次,然后通过JSONObject结构递归。换句话说,递归函数应该采用JSONObject
  • 只需将JSON元素替换到位
  • 或者,如果要将元素展平并将其收集到
    映射
    ,则先实例化
    映射
    ,然后将其传递到递归函数中

要更轻松地转换,您可以使用lib来执行硬操作:

ObjectMapper mapper = new ObjectMapper();
String jsonString = "{  
   "data":{  
      "attributes":{  
         "external-event-url":"http://example.com",
         "is-sponsors-enabled":"true",
         "is-ticketing-enabled":"true",
         "timezone":"UTC",
         "name":"${name_variable}",
         "ends-at":"2020-01-02T23:59:59.123456+00:00",
         "starts-at":"2020-01-01T23:59:59.123456+00:00"
      },
      "type":"event"
   }
}";

// considering JSONObject matches the Json object structure
JSONObject jsonObject = mapper.readValue(jsonString , JSONObject.class); 
然后,需要一点时间来动态处理任何JSON对象字段:

// with parsed JSON to Object in hands
Class<?> clazz = jsonObject.getClass();

for(Field field : clazz.getDeclaredFields()) {
    if(!field.getType().getName().equals("String"))
        break;

    field.setAccessible(true);
    String fieldValue = field.getValue().toString();

    if(fieldValue.startsWith("${"))
        field.set(jsonObject, fieldValue.replace("${", "").replace("}", ""));
    else
        // desired treatment
}
//将解析后的JSON传递到手中的对象
类clazz=jsonObject.getClass();
for(字段:clazz.getDeclaredFields()){
如果(!field.getType().getName().equals(“字符串”))
打破
字段。setAccessible(true);
字符串fieldValue=field.getValue().toString();
if(fieldValue.startsWith(“${”))
set(jsonObject,fieldValue.replace(“${”,”).replace(“}”,”);
其他的
//理想治疗
}

“如何迭代如此复杂的Json对象并替换变量中的值?”,递归。如果它是一个JSONObject,那么进入它并迭代它的子对象。如果子对象是一个JSONObject,那么递归。@xtratic,这就是我试图实现相同逻辑的原因。但是我不知道我犯了什么错误。问问你自己,仅仅替换整个JSON文本是否更好。但是如果你决定不这样做,然后,最好先将JSON转换为对象,然后调用一个接受JSONObject而不是字符串的递归方法,并避免从字符串到对象以及从字符串到对象的所有转换。请发布所有代码。什么是JSONVALID()类似于?@StvnBrkdll,已更新。此方法用于检查特定键的值是否为JSON对象,如果是,则返回
// with parsed JSON to Object in hands
Class<?> clazz = jsonObject.getClass();

for(Field field : clazz.getDeclaredFields()) {
    if(!field.getType().getName().equals("String"))
        break;

    field.setAccessible(true);
    String fieldValue = field.getValue().toString();

    if(fieldValue.startsWith("${"))
        field.set(jsonObject, fieldValue.replace("${", "").replace("}", ""));
    else
        // desired treatment
}