The interface com.liferay.portal.kernel.json.JSONObject and its implementation com.liferay.portlet.json.JSONObjectImpl (a wrapper to the org.json's library) does not provide the JSONObject.NULL (but the native's org.json does).
This is a potential issue because actually there is no way using the Liferay json APIs to serialize a JSONObject instance having one or more null values, because each null Java object reference will be ignored by the toJSONString() method as well as the related entry keys.
The original org.json.JSONObject implementation, instead, provides a JSONObject.NULL static final field, that will be converted in the null value during the serialization in toJSONString().
Liferay APIs, instead, does not provide the JSONObject.NULL so the Liferay APIs user has no way to use it.
null values are and this may be a potential problem when you have to call, for instance, a remote service that requires a particular field as mandatory in the serialized JSON request. For more informations about that issue please see: http://www.json.org and the first lines of comment of the original JSONObject implementation: https://github.com/stleary/JSON-java/blob/master/JSONObject.java.
JSONObject jo = JSONFactoryUtil.createJSONObject();
The output will be:
instead of the expected one:
So the only way to get the null object reference in JSON serialization using the com.liferay.portal.kernel.json APIs, is to provide a wrapper for the org.json.JSONObject.NULL field in the JSONFactoryUtil, for example, so the user can put this reference as value in the JSONObject.put(key, value).