json-processing-spec
  1. json-processing-spec
  2. JSON_PROCESSING_SPEC-53

Replace generic get methods in JsonArray & JsonObject with specific getters for object, array & number

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.0-pfd
    • Labels:
      None

      Description

      Example of how this change affects a typical task such as pulling a numeric value out of a nested object:

      Given a JSON data structure:

          {
              "id": 1234,
              "location": {
                  "lat": 39.12333432,
                  "long": -79.12344534
              }
          }
      

      fetch the latitude from the nested "location" object.

      BEFORE:

          JsonObject jo = ...;
          double lat = jo.get("location", JsonObject.class).get("lat", JsonNumber.class).getDoubleValue();
      

      AFTER:

          JsonObject jo = ...;
          double lat = jo.getObject("location").getNumber("lat").doubleValue();
      

      I've implemented this together with shortening of getter names (drop 'Value' from getter method names; adjusted JsonNumber to use the familiar java.lang.Number method naming convention)

      You can play with it by pulling from here:

      https://github.com/jfuerth/javax-json/commit/c88ec370a78154fa348758b9edbf022cf746d301

        Activity

        Hide
        jitu added a comment -

        I think JsonNumber names should be in a separate issue. We have the same names in other places, for e.g JsonParser#getIntValue()

        Show
        jitu added a comment - I think JsonNumber names should be in a separate issue. We have the same names in other places, for e.g JsonParser#getIntValue()
        Hide
        jfuerth added a comment -

        Oh, good catch! I thought I had found all of them. I'll open a separate issue.

        Show
        jfuerth added a comment - Oh, good catch! I thought I had found all of them. I'll open a separate issue.
        Hide
        jfuerth added a comment -

        I removed 'Value' from the method names in JsonParser. The commit is available for review on the same branch at:

        https://github.com/jfuerth/javax-json/commit/shorter-method-names

        Show
        jfuerth added a comment - I removed 'Value' from the method names in JsonParser. The commit is available for review on the same branch at: https://github.com/jfuerth/javax-json/commit/shorter-method-names
        Hide
        jitu added a comment - - edited
        • You noted earlier, one thing unsettling is getObject/getArray/getNumber return JsonXXX, where as getString return String
        • Should we use getJsonObject/getJsonArray etc? It is bit long.
        double lat = jo.get("location", JsonObject.class).get("lat", JsonNumber.class).getDoubleValue();
        

        would be

        double lat = jo.getJsonObject("location").getJsonNumber("lat").getDouble();
        
        • Since there are accessor methods for string, int (perhaps the common cases), should we just add array and object accessor methods.
        Show
        jitu added a comment - - edited You noted earlier, one thing unsettling is getObject/getArray/getNumber return JsonXXX, where as getString return String Should we use getJsonObject/getJsonArray etc? It is bit long. double lat = jo.get( "location" , JsonObject.class).get( "lat" , JsonNumber.class).getDoubleValue(); would be double lat = jo.getJsonObject( "location" ).getJsonNumber( "lat" ).getDouble(); Since there are accessor methods for string, int (perhaps the common cases), should we just add array and object accessor methods.
        Hide
        jfuerth added a comment -

        That sounds like a reasonable solution to me. Adding "Json" to the names of methods that return JsonValues eliminates the potential confusion.

        Closely related issue:

        In the change I made for review, I eliminated the JsonObject#get(String,Class) and JsonArray#get(int,Class). This means that it's no longer possible to retrieve a JsonString instance from an object or an array (you can only get the java.lang.String that the JsonString wraps). I didn't add a special method for obtaining the JsonString mostly because the getString() that returns java.lang.String was in the way. It doesn't seem like a big problem to me.

        I can only see one potential use case for getting the JsonString wrapper held by a JsonObject or JsonArray: when copying a bunch of string values from a JsonObject to a JsonObjectBuilder, passing the unwrapped strings to the builder will require new JsonString wrapper instances to be created, whereas this could be avoided by passing the JsonString wrapper that the JsonObject was already using. The same does not go for arrays, because we can use JsonArray#asList(JsonString.class) to get at the wrappers.

        What do you think? If we rename getObject -> getJsonObject, getArray -> getJsonArray(), getNumber() -> getJsonNumber(), should we also add a getJsonString()?

        Show
        jfuerth added a comment - That sounds like a reasonable solution to me. Adding "Json" to the names of methods that return JsonValues eliminates the potential confusion. Closely related issue: In the change I made for review, I eliminated the JsonObject#get(String,Class) and JsonArray#get(int,Class). This means that it's no longer possible to retrieve a JsonString instance from an object or an array (you can only get the java.lang.String that the JsonString wraps). I didn't add a special method for obtaining the JsonString mostly because the getString() that returns java.lang.String was in the way. It doesn't seem like a big problem to me. I can only see one potential use case for getting the JsonString wrapper held by a JsonObject or JsonArray: when copying a bunch of string values from a JsonObject to a JsonObjectBuilder, passing the unwrapped strings to the builder will require new JsonString wrapper instances to be created, whereas this could be avoided by passing the JsonString wrapper that the JsonObject was already using. The same does not go for arrays, because we can use JsonArray#asList(JsonString.class) to get at the wrappers. What do you think? If we rename getObject -> getJsonObject, getArray -> getJsonArray(), getNumber() -> getJsonNumber(), should we also add a getJsonString()?
        Hide
        jitu added a comment -

        I was planning to add a method for JsonString. But anyway, developers can always use get(string/index) and cast it.
        I will do the changes and you can take a look at it.

        Show
        jitu added a comment - I was planning to add a method for JsonString. But anyway, developers can always use get(string/index) and cast it. I will do the changes and you can take a look at it.
        Hide
        jitu added a comment -

        Removed
        getValue(..., ...)

        Added
        JsonArray getJsonArray(...)
        JsonObject getJsonObject(...)
        JsonNumber getJsonNumber(...)
        JsonString getJsonString(...)
        boolean isNull(...)

        Show
        jitu added a comment - Removed getValue(..., ...) Added JsonArray getJsonArray(...) JsonObject getJsonObject(...) JsonNumber getJsonNumber(...) JsonString getJsonString(...) boolean isNull(...)

          People

          • Assignee:
            Unassigned
            Reporter:
            jfuerth
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Due:
              Created:
              Updated:
              Resolved: