Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@effad
Copy link
Contributor

@effad effad commented May 17, 2017

This fix provides additional API for creating JSONObject and JSONArray instances in the way requested by myself in Issue 296: Java null should become JSON null.

The behaviour of the existing API (i.e. without the useJavaNullAsJsonNull) will not be changed by this fix.

I also created some regression tests in the JSONArrayTest and JSONObjectTest from the JSON-Java-unit-test repository which I attach as ZIP-File.

Tests.zip

effad and others added 2 commits May 16, 2017 15:01
This fix provides additional ways to create JSONObject and JSONArray instances that will handle Java
null values as JSON null values.
cf. stleary#296 for extensive discussion.
@johnjaylward
Copy link
Contributor

would you be able to create a PR for the tests as well under the test project:

https://github.com/stleary/JSON-Java-unit-test

@johnjaylward
Copy link
Contributor

Overall these changes are straightforward and match what I expected in #296. I think if you can get the changes to the tests as a PR instead of a zip, you'll have a good case for the change. I personally have no issue with the API changes.

if (object instanceof Map) {
Map<?, ?> map = (Map<?, ?>) object;
return new JSONObject(map);
return new JSONObject(map, useJavaNullAsJsonNull);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should also update lines 1852 and 1855 to use the new JSONArray constructors:

if (object instanceof Collection) {
                 Collection<?> coll = (Collection<?>) object;
                 return new JSONArray(coll, useJavaNullAsJsonNull);
             }
             if (object.getClass().isArray()) {
                 return new JSONArray(object, useJavaNullAsJsonNull);
              }

Nested arrays and beans now also respect the new parameter correctly.
@stleary
Copy link
Owner

stleary commented May 24, 2017

Would this be a first use in this lib of a boolean constructor param to control behavior?

@johnjaylward
Copy link
Contributor

In these classes. The XML class uses a similar control, although I'm not a huge fan of the design pattern (I did it first in the XML class).

In another ticket I mentioned that using the boolean flags may have been a bad choice, and instead we should have a configuration object.

public class XMLConfig {
   public boolean someConfigOption;
   public boolean someOtherConfigOption;
}

maybe to future proof this change, we should consider a similar concept.

public class JSONParseConfig {
   public boolean useJavaNullAsJsonNull;
   public JSONParseConfig () { super(); }
   public JSONParseConfig setUseJavaNullAsJsonNull(final boolean useJavaNullAsJsonNull) {
      this.useJavaNullAsJsonNull = useJavaNullAsJsonNull;
      return this;
}

The setter would return the config object so you could chain configuration options:

new JSONObject(someJsonString,
   new JSONParseConfig().setUseJavaNullAsJsonNull(true).setSomeFutureOption(true)
);

@stleary
Copy link
Owner

stleary commented May 25, 2017

Control params are arguably not a great design pattern, but the greater concern to me are the potential follow up requests for special handling of numeric types, XML, and so forth. A config object might work better, but might also open a Pandora's box of future customizations. It could be that forking the project is the best solution in this case. Otherwise, how far are we willing to depart from being a simple reference app? Let me know what you think @effad and @johnjaylward.

@effad
Copy link
Contributor Author

effad commented May 25, 2017

I can see and understand the concern about people requesting future customization. And yes, forking is an absolutely viable way of getting the desired behaviour into a library.
However, given the very widespread use of JSON-java, I think it is also a problem if loads of forks exist because it will require people to apply the same changes over and over again to the detriment of each fork. (As could be seen here: My "fix" required careful review and a second iteration to be (hopefully) correct.)

In the special case of Issue 296 I would argue that it actually fixes/addresses a (admittedly very old) regression. The behaviour brought back here is that of a very old version of the library and people (like me) may need to have this behaviour while at the same time not wanting to write/maintain their own version of the library.

As to boolean parameter vs. configuration object: I don't have a very strong opinion there. Both ways are ok for me and I can see the advantage of extensibility in a JSONParseConfig-object.

@johnjaylward
Copy link
Contributor

I think we should accept this change, either as-is or swapped with the config-object. The original issue (#296 (comment)) @effad opened explained it pretty well, and I think it's a valid use case for the parser/object mapper.

Using the config object could possibly also bring forward support for strict parsing like mentioned in #240 and #269.

I'm not sure we necessarily want to support that per-say, but I think we could handle that on a PR-by-PR basis.

This PR looks simple enough and I think if @effad could post those test changes that are currently in a zip to the test project as a PR it would be easier to check and easy enough to support.

@johnjaylward
Copy link
Contributor

Ah, I found the tests here: stleary/JSON-Java-unit-test#72

@stleary
Copy link
Owner

stleary commented May 26, 2017

@effad This project already has > 1900 forks, currently averaging 1 every day or so. Can't agree that the current behavior is a regression, since it seems clearly intended to be a design change. But I think your other points have merit.
@johnjaylward Did you want to address the question of how far are we willing to depart from being a simple reference app? Do you not consider that a priority? I need a little time to get up to speed on your comments about #240 and #269.

@johnjaylward
Copy link
Contributor

For the remarks as a reference app, I feel this issue still falls in that purview. In general would like to see this project stay small, but also useful to the most people out there. If someone needs something full featured with all the bells and whistles, that's what projects like https://github.com/FasterXML/jackson are for.

Being able to maintain the "null" data in their JSON representations seems like a valid thing a reference app should handle to me. I guess what it comes down to is a difference in opinion on which features should be considered "reference". Kinda makes me wish GitHub had a talk page like wikis 😄.

My main argument for the configuration object is in case there are other "reference" items we may wish to support. The "Strict parsing" like mentioned in those other 2 tickets is what came to mind. Strict parsing seems very much like something a reference library would handle. I personally like the loose parsing and wouldn't use the strict parsing, but others have requested it.

@stleary
Copy link
Owner

stleary commented May 27, 2017

Fair enough, the team agrees that this is a worthwhile enhancement, so a code change can proceed, within the constraints of the project. Would it be accurate to say the entire pull request comes down to deciding whether to call JSONOjbect.wrap()? If so, it would be better if we can come up with something that does not require passing control parameters or config objects down to the places where the code is actually needed. New proposed code can be updated in this pull request, or a new PR started.

Not inclined to consider support for strict parsing until/unless @douglascrockford indicates that this would be a good direction to take the project.

@stleary
Copy link
Owner

stleary commented Aug 11, 2017

Thanks for the pull request, but can't be accepted at the present time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants