5

I am getting the data from the Zookeeper node like this

byte[] bytes = client.getData().forPath("/my/example/node1");
String ss = new String(bytes);

Here ss will have data like this which is a simple JSON String consisting of key value pair -

{"description":"Some Text", "machinename":"machineA", "ipaddress":"192.128.0.0"}

Now I want to append one more key value pair at the end to the above JSON String. This is the below key value pair I want to append -

"version":"v3"

So the final JSON String will look like this -

{"description":"Some Text", "machinename":"machineA", "ipaddress":"192.128.0.0", "version":"v3"}

What's the best and efficient way to do this?

9
  • 1
    As a general rule, don't. You can do it, in limited cases, by doing the obvious string manipulations, but it's far better, in the general case, to deserialize the JSON, modify the resulting Map, and then reserialize the Map. Commented Jan 8, 2014 at 21:26
  • 1
    You need a JSON parser. Commented Jan 8, 2014 at 21:27
  • @HotLicks unless you can give a real reason, I don't buy that argument. Especially if he's just learning. Don't over engineer the problem. Commented Jan 8, 2014 at 21:52
  • 1
    Please, please PLEASE specify a charset when using the String constructor that takes an array of bytes, otherwise your code will break if the platform's default encoding is not what you expect. For JSON, you want UTF-8, so: new String(bytes, StandardCharsets.UTF_8) Commented Jan 8, 2014 at 21:54
  • @SLaks You are correct. Using string manipulation to produce (or, even worse, edit) JSON strings is a VERY bad idea in general. Commented Jan 8, 2014 at 22:02

3 Answers 3

10

Use a JSON Parser/Generator to parse your given JSON to a tree structure and then add your JSON field.

With Gson, that would look something like this

Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(ss, JsonObject.class); // parse
jsonObject.addProperty("version", "v3"); // modify
System.out.println(jsonObject); // generate

prints

{"description":"Some Text","machinename":"machineA","ipaddress":"192.128.0.0","version":"v3"}

Will Zookeeper always return valid JSON or their custom format? Be aware of that.

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

6 Comments

Thanks. Yes Zookeeper will always return Valid JSON because in that format only (JSON document) I am storing the data inside the node. So when I am retrieving it, it gives me back the same JSON String which I have written earlier..
Jackson JSON library is widely used.
If he wants the most efficient way, this is overkill.
@DanielNuriyev Absolutely, Jackson's ObjectMapper has a corresponding method to give you an ObjectNode.
@Zaphod42 Efficiency doesn't only apply to how fast code executes. It has to do with writing the code, maintaining it, etc.
|
2

When it comes to JSON processing, string manipulation only works in special and simple cases. For the general case, a good JSON parser library should be used.

Jackson is among the top of such libraries in terms of performance, efficiency, versatility and reliability, plus it is published under the commercial-friendly Apache 2.0 license.

Following is a simple implementation of the requested answer in Jackson.

public static void main(String[] args)
{
    String ss = "{\"description\":\"Some Text\", \"machinename\":\"machineA\", \"ipaddress\":\"192.128.0.0\"}";

    System.out.println("JSON string before: " + ss);

    try
    {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, String> map = (Map<String, String>)mapper.readValue(ss, Map.class);
        
        map.put("version", "v3");
        ss = mapper.writeValueAsString(map);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    System.out.println("JSON string after: " + ss);
}

2 Comments

It might be easier to use the ObjectMapper method that gives you a JsonNode, cast it to an ObjectNode and modify that.
Correct, I just opted for simplicity of explanation. I do prefer JsonNode in real world code. Thanks.
1

Basic string manipulation. Insert your additional string before the final close brace }. Make sure to add a comma.

Json objects don't need to be ordered.

String json = "{\"key1\":\"value1\",\"key2\":\"value2\"}";

String json2 = "\"version\":\"v3\"";

json2 = ',' + json2;

String json3 = json.substring(0,json.length()-1) + json2 + json.charAt(json.length()-1);

That should be the simplest, most efficient way, if that's all you need to do.

For additional reading on String manipulation,

http://docs.oracle.com/javase/tutorial/java/data/manipstrings.html

11 Comments

Yes it will, and yes it is. I'm using ' instead of ", you should really use " and escape them, but otherwise this is correct.
Try to compile it. The error is tiny, but I want you to fix it.
I hope this exercise demonstrated how inefficient it was to generate your own JSON case by case.
@Zaphod42 Using string manipulation to produce (or, even worse, edit) JSON strings is a VERY bad idea in general. For simple cases it may work, but this does not make it good programming style. I have upvoted your answer because I consider negative marks as disrespectful (at least when an answer is decent), but what Sotirios said is correct and there is no need for tension. :-)
Sure, but as you know programming is not about special cases and JSON processing in general should not be done via string processing. Even the slightest addition to a JSON string may break it, especially if it comes from user input that may have special characters, which need to be escaped. JSON manipulation should always happen via a JSON parser.
|

Your Answer

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