I don't understand why the last row of this code return a empty string.
Map<String, JsonObjectBuilder> HASH_MAP = new HashMap<>();
JsonObjectBuilder one = Json.createObjectBuilder();
one.add("test1","test1");
HASH_MAP.put("one", one);
JsonObjectBuilder two = Json.createObjectBuilder();
two.add("test2","test2");
HASH_MAP.put("two", two);
JsonObjectBuilder toReturn = Json.createObjectBuilder();
JsonArrayBuilder l1 = Json.createArrayBuilder();
for (Map.Entry<String, JsonObjectBuilder> l : HASH_MAP.entrySet()) {
l1.add(l.getValue());
}
toReturn.add("l1", l1);
toReturn.add("otherParam", "value2");
String strJSON = toReturn.build().toString();
System.out.println("JSON1: " + strJSON);
System.out.println("JSON2: " + HASH_MAP.get("one").build().toString());
This is the output:
Info: JSON1: {"l1":[{"test1":"test1"},{"test2":"test2"}],"otherParam":"value2"}
Info: JSON2: {}
I am espetting that the second JSON is {"test1":"test1"}
. I am wrong?
The problem seems to be link with the .build()
function that sets all the valueMap of elements added to the HASH_MAP
to null (see the image).
How can I leave the value inside the HASH_MAP
untouched?
After build()
ing a JsonObject
from a JsonObjectBuilder
the builder is cleared to be ready for reuse. To illustrate this:
JsonObjectBuilder b = Json.createObjectBuilder();
b.add("foo", "bar");
JsonObject o = b.build();
JsonObject p = b.build();
System.out.println(o.toString()); // {"foo":"bar"}
System.out.println(p.toString()); // {}
When you do
l1.add(l.getValue()); // l.getValue() is (JsonObjectBuilder) one at some time
build()
is called implicitly on one
, hence it is emptied.
Then here:
System.out.println("JSON2: " + HASH_MAP.get("one").build().toString());
you build the representation of an empty JsonObject
.
To migitate this, you could for example store JsonObjects instead of JsonObjectBuilders in your hashmap:
Map<String, JsonObject> HASH_MAP = new HashMap<>();
JsonObjectBuilder one = Json.createObjectBuilder();
one.add("test1","test1");
HASH_MAP.put("one", one.build());
JsonObjectBuilder two = Json.createObjectBuilder();
two.add("test2","test2");
HASH_MAP.put("two", two.build());
JsonObjectBuilder toReturn = Json.createObjectBuilder();
JsonArrayBuilder l1 = Json.createArrayBuilder();
for (Map.Entry<String, JsonObject> l : HASH_MAP.entrySet()) {
l1.add(l.getValue());
}
toReturn.add("l1", l1);
toReturn.add("otherParam", "value2");
String strJSON = toReturn.build().toString();
System.out.println("JSON1: " + strJSON);
System.out.println("JSON2: " + HASH_MAP.get("one").toString());
Now it should work as you expect.
Keep in mind that the call to build()
flush the value stored in your object one
JSonObjectBuilder, so you can call only one time the method build(), If you call it again you go to have the representation of an empty JSonObject
. Ex:
one.add("test1","test1");
System.out.println(one.build())
System.out.println(one.build())
the output:
{"test1":"test1"}
{}
If you really want to call it again, you have to add again the value that you want. Ex:
one.add("test1","test1");
System.out.println(one.build())
one.add("test1","test1")
System.out.println(one.build())
the output:
{"test1":"test1"}
{"test1":"test1"}
As @Ctx says, you could put in your map JsonObjects instead of JsonObjectBuilders, so put as value of your map the JsonObject returned by the call of the method build().
Ex:
HASH_MAP.put("one", one.build());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With