JSON-java icon indicating copy to clipboard operation
JSON-java copied to clipboard

Creating JSONObject from Map vs String misses null values

Open alexisml opened this issue 3 years ago • 4 comments

If we create a JSONObject from a string containing null values, those are parsed internally as JSONObject.NULL [see 1]. However, when creating a JSONObject from a Map, null values are ignored [see 2].

This is a problem since we have an inconsistency. Either both cases ignore nulls (this wouldn't represent reality), or both convert Java nulls to JSONObject.NULL.

1: https://github.com/stleary/JSON-java/blob/7d6b76de375f8fbde93226ed77dbf51e4c70e29a/src/main/java/org/json/JSONObject.java#L2309-L2311 2: (there's no ELSE) https://github.com/stleary/JSON-java/blob/7d6b76de375f8fbde93226ed77dbf51e4c70e29a/src/main/java/org/json/JSONObject.java#L307-L309

alexisml avatar Feb 21 '22 20:02 alexisml

This is as-designed.

When parsing a String, we are parsing actual JSON where null is a value.

When transforming a Map, in Java, null means "no value" which is similar to undefined in JavaScript. The author of this library made the conscious choice to treat Java null like JavaScript undefined.

Whether or not that was the best choice is a little late for this project as it would be a breaking change for people that have been using this project for 20 or so years.

johnjaylward avatar Feb 21 '22 21:02 johnjaylward

Whether or not that was the best choice is a little late for this project as it would be a breaking change for people that have been using this project for 20 or so years.

Thi is completely understandable. However, I still believe it could be solved, maybe by using a second parameter indicating to threat nulls as Json nulls... (just an idea).

Regarding...

When transforming a Map, in Java, null means "no value"

...this is not exactly true: since there's still a key in the Map for that value, and all methods regarding Maps threat that as an explicit <key, null> entry.

alexisml avatar Feb 21 '22 21:02 alexisml

Java is a strongly typed language and null does not have a type. A variable assigned null has no value as it's un-typed.

JavaScript is an un-typed/loosely-typed language, so null is an actual value.

johnjaylward avatar Feb 21 '22 21:02 johnjaylward

This design does not seem internally consistent. I think it would be reasonable to expect JSONObject.toMap to be the inverse of new JSONObject(Map).

new JSONObject("{k:null}") includes the null-valued entry new JSONObject("{k:null}").toMap() includes the null-valued entry new JSONObject(new JSONObject("{k:null}").toMap()) drops the null-valued entry

labkey-tchad avatar Oct 17 '22 21:10 labkey-tchad

Closing this issue since no fix was proposed. The inconsistency is noted, but changing current behavior might break existing applications. If anyone disagrees, please post here.

stleary avatar Sep 30 '23 04:09 stleary