users@jsonp.java.net

Re: Sequence of creating JsonObjectBuilder and JsonArrayBuilder interferes in the final result

From: Hildeberto Mendonça <hildeberto_at_yougi.org>
Date: Thu, 24 Oct 2013 22:30:17 +0200

Hello Jitu,

Em 24/10/13 21:18, Jitendra Kotamraju escreveu:
> On 10/23/13 1:18 PM, Hildeberto Mendonça wrote:
>> Hello,
>>
>> I'm creating some Json content using the Object Model API and I
>> realized that the sequence of creating JsonObjectBuilder and
>> JsonArrayBuilder actually interferes in the final result. The
>> following code won't include the categories in the resulting Json:
>> List<CategoryMenu> categories = categoryMenuBean.findCategoriesByMenu(menu);
>> JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
>> JsonArrayBuilder arrayBuilderCategories = Json.createArrayBuilder();
>> objectBuilder.add("categories", arrayBuilderCategories);
>>
>> for(CategoryMenu category: categories) {
>> arrayBuilderCategories.add(Json.createObjectBuilder()
>> .add("id", category.getId())
>> .add("name", category.getName()));
>> }
>>
>> JsonObject model = objectBuilder.build();
>> StringWriter strWriter = new StringWriter();
>> try (JsonWriter jsonWriter = Json.createWriter(strWriter)) {
>> jsonWriter.writeObject(model);
>> }
>> System.out.println(strWriter.toString()); // output = []
>>
>> To fix the problem, I have to move the highlighted line to after the
>> iteration:
>> List<CategoryMenu> categories = categoryMenuBean.findCategoriesByMenu(menu);
>> JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
>> JsonArrayBuilder arrayBuilderCategories = Json.createArrayBuilder();
>>
>> for(CategoryMenu category: categories) {
>> arrayBuilderCategories.add(Json.createObjectBuilder()
>> .add("id", category.getId())
>> .add("name", category.getName()));
>> }
>> objectBuilder.add("categories", arrayBuilderCategories);
>> JsonObject model = objectBuilder.build();
>> StringWriter strWriter = new StringWriter();
>> try (JsonWriter jsonWriter = Json.createWriter(strWriter)) {
>> jsonWriter.writeObject(model);
>> }
>> System.out.println(strWriter.toString()); // output ={"categories":[{"id":1,"name":"Plat du Jour"},{"id":2,"name":"Permanent"}]}
>> In my humble opinion it should work in both cases because it gives
>> more flexibility to the programmer. Is it supposed to work like that
>> or is it an issue?
> I don't consider it as an issue. What you are suggesting is a lazy
> construction of JsonObject/JsonArray from the associated builders when
> the final build happens. This may be ok for one level, but if the
> constructed JsonObject is big tree, then one has to walk down the tree
> and build those objects from the associated builders.

I still consider it as an issue because constructions like that works
very well in APIs such as Java Swing, JavaFX, JAXP and other libraries.
I this it should also work for JSONP because developers used to those
libraries will expect that from JSONP too. There is the possibility of
other implementations doing this to give more flexibility to developers.
It would be a potential behavior difference that would cause many
problems for those people migrating from a supplier to another. That's
the main problem JSRs aim to address.

I think this is just a matter of algorithm design. Objects have
references to other objects, so "objectBuilder" has a reference to
"arrayBuilderCategories". Since this is a object model API, the final
Json content would be extracted from the final model construction. I
would agree with you in the case of the Stream API, since performance is
a relevant constraint, but not in the case of the object model API.

Please, let me know what you think.

Regards,

Hildeberto