3

We have a requirement to update the JSON data in middle and need to return the updated JSON data using java. Also it should support any type of JSON data.

ex: Assume {object:{"color":"red","shape":"Triangle"}} is the JSON data and in this we need to update the shape value to Rectangle and we need to return the updated JSON data as below:

{object:{"color":"red","shape":"Rectangle"}}

For this we need to pass the element path ( which element we need to update) and updateText and JSON Data to the JAVA code.

here is the methodCall:

updateValue("object/shape", "Rectangle", "{object:{"color":"red","shape":"Triangle"}}")

We tried below code using Gson library. But with this code we are able to update the targeted Json element, but the requirement is to return the entire JSON data with the updated value.

So please suggest how do we re-build the JSON data with the updated text.

Below is the code we tried to update the Json Data.

    public String updateValue(String keyPath, String updateText, String jsonText) {
    String[] keys = keyPath.split("/");
    JsonParser jsonParser = new JsonParser();
    JsonObject jsonObject = (JsonObject) jsonParser.parse(jsonText);
    String result = "";
    for(String key : keys)
    {
        if (jsonObject.get(key) instanceof JsonObject)
        {
          jsonObject = (JsonObject)jsonObject.get(key);
        }
        else if(jsonObject.get(key) instanceof JsonArray)
        {
          JsonArray jsonArray = (JsonArray)jsonObject.get(key);
          result = jsonArray.toString();
        }
        else 
        {
          result = jsonObject.get(key).toString();
        }           
    }
    result = result.replace(result, updateText);
    return result;      
}
Prudhvi
  • 2,276
  • 7
  • 34
  • 54
ramesh sriram
  • 67
  • 1
  • 2
  • 11

2 Answers2

1

The problem lies in the way you do the replacements. When you translate the JsonObject to String, you lose the object, and after replacement, you just have the replaced String. To fix it, you need to operate directly on the object, instead of the String counterpart. Because JsonObject is mutable, holding a reference to the input will reflect the changes. One drawback is you can't replace a value in a JsonArray this way, partly because you don't know which element to replace. To accomplish that, you will need a little more in the input(either the value to replace or the element position).

public String updateValue(String keyPath, String updateText, String jsonText) {
    String[] keys = keyPath.split("/");
    JsonParser jsonParser = new JsonParser();
    JsonObject jsonObject = (JsonObject) jsonParser.parse(jsonText);
    JsonObject returnVal = jsonObject; // This holds the ref to target json object
    JsonPrimitive jp = new JsonPrimitive(updateText);
    String finalKey = keys[keys.length - 1];
    for(String key : keys)
    {
        if (jsonObject.get(key).isJsonObject())
        {
            jsonObject = (JsonObject)jsonObject.get(key);
        }
    }
    jsonObject.remove(finalKey);
    jsonObject.add(finalKey, jp);
    return returnVal.toString();      
}
Pradeep Pati
  • 5,779
  • 3
  • 29
  • 43
  • Hi Praddep, Thanks for your response. In this code **returnVal** refers to the variable **jsonObject** which modifies inside for loop. And fin'ly it returns the inner most JSONObject which contains our JSON value either JSONArray or value. ex: In this ex this code returns `{"color":"red","shape":"Triangle"}` and omits `{"Object"}` It should return: `{object:{"color":"red","shape":"Rectangle"}}` ( It should re-build the entire JSON object with the modified val) – ramesh sriram Apr 23 '15 at 02:56
0

You can use JsonPath lib for that and try using the following code.

private static final Configuration configuration = Configuration.builder()
     .jsonProvider(new JacksonJsonNodeJsonProvider())
     .mappingProvider(new JacksonMappingProvider())
     .build();

JsonNode updatedJson = JsonPath.using(configuration).parse(originaljson)
     .set("use the path to go for value", "new value").json();
json = updatedJson.toString();
Guido
  • 46,642
  • 28
  • 120
  • 174