25

here is the json file

{
    "session":
        {
            "name":"JSESSIONID",
            "value":"5864FD56A1F84D5B0233E641B5D63B52"
        },
    "loginInfo":
        {
            "loginCount":77,
            "previousLoginTime":"2014-12-02T11:11:58.561+0530"
        }
}

I want to change the value of name.by directly giving XPath/JsonPath Like

($.session.name).changevalue("MYSESSINID") this is just a Example

I am correctly using jackson library and using the below code for reading via XPath

ObjectMapper mapper = new ObjectMapper();

        Object jsonObj=mapper.readValue(new File(Json file), Object.class);
        Object name=PropertyUtils.getProperty(jsonObj, "session.name");
        System.out.println("Name:"+name);

so is their a way to change the name by XPath

PropertyUtils.setProperty(jsonObj, "session.value", "new value");

still in the file its not working.

7
  • PropertyUtils has a setProperty method as well, have you tried that? Commented Dec 2, 2014 at 8:03
  • @flup setProperty code is not working its not giving any error but its not changing the value either Commented Dec 2, 2014 at 8:56
  • The object tree lives in memory only. So after you change the value in the object tree, you have to serialize it back to file. Commented Dec 2, 2014 at 9:01
  • @flup <br/> PropertyUtils.setProperty(jsonObj, "session.name", "lkihilh"); mapper.writeValue(json file ,jsonObj); this will write the entire json code in a file if the file is big it consume a lot of time Is their in other way to do it Commented Dec 2, 2014 at 9:48
  • 1
    Probably best to create a new question for the new question :) Commented Dec 3, 2014 at 14:45

4 Answers 4

48

Using Jayways JsonPath you can:

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

@Test
public void a_value_can_be_updated(){

    String originalJson = "{\n"
        + "\"session\":\n"
        + "    {\n"
        + "        \"name\":\"JSESSIONID\",\n"
        + "        \"value\":\"5864FD56A1F84D5B0233E641B5D63B52\"\n"
        + "    },\n"
        + "\"loginInfo\":\n"
        + "    {\n"
        + "        \"loginCount\":77,\n"
        + "        \"previousLoginTime\":\"2014-12-02T11:11:58.561+0530\"\n"
        + "    }\n"
        + "}";

    JsonNode updatedJson = JsonPath.using(configuration).parse(originalJson).set("$.session.name", "MYSESSINID").json();

    System.out.println(updatedJson.toString());
}

You can configure the default JsonProvider so you don't have to pass it in all calls.

Sign up to request clarification or add additional context in comments.

4 Comments

I tried your solution but it is setting a number value as string. Any solution to this? eg : tried to set login count to 1, it was returned as : "loginCount":"1"
Oh found the solution! Pass integer object to set as int
What if multiple nodes are matched? Looks like there's a need for something like "forEach" with custom handler that could handle nodes of any types.
Note that this only works if the specified key already exists.
3
PropertyUtils.setProperty(jsonObj, "session.value", "new value");
        PropertyUtils.setProperty(jsonObj, "session.name", "new name");
        mapper.writeValue(Json File ,jsonObj);

2 Comments

Unfortunately, mapper is not defined so this doesn't work.
What's "mapper"?
3

the easiest way i found to exchange inside Json (When my Body is a JSONObject)

import com.jayway.jsonpath.JsonPath;


JsonPath.parse(Body).set(fieldPath, Value);

Comments

0

I tried Kalle's way, it always said jsonPath not found when I am adding a new field.

So I used this updated way to add a new field

        @Test
        public void a_node_can_be_updated_and_created() throws ParseException{
        
        System.out.println(originalJson);
        JSONObject json = (JSONObject)new JSONParser(JSONParser.DEFAULT_PERMISSIVE_MODE).parse(originalJson);
        JSONObject session = JsonPath.read(json, "$.session");
        session.appendField("new__field", "new__value");        // add a new field
        session.put("name", "Justin2");                         // update an existing field
        System.out.println(JsonFormatter.prettyPrint(json.toJSONString()) );
        
    }

This new way also doesn't need Jackson library, only Jayway.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.