Over a million developers have joined DZone.

Making Your JSON-P (JSR-353) Code Slightly Prettier

· Java Zone

Discover how powerful static code analysis and ergonomic design make development not only productive but also an enjoyable experience, brought to you in partnership with JetBrains

The JSON-P API as described in JSR-353 is a limited API for working with JSON; but at the basic level it will do the job. It is possible to add a few utility methods that can make your code, in my eyes, prettier.

The first think that annoyed me was the use of Json.createObjectBuilder() andJson.createArrayBuilder() when trying to construct a JSONObject.

So lets create a nice helper class with some very short method names for both:

public static JsonObjectBuilder ob() {
  return Json.createObjectBuilder();
}

public static JsonArrayBuilder ab() {
  return Json.createArrayBuilder();
}

This makes the creation of object just that little bit less wordy:

JsonObject object = ob()
  .add("hello", "world")
  .add("fark", ".com")
  .add("fish", ob()
    .add("child", "child"))
  .add("array", ab()
    .add("one")
    .add("two")
    .add(ob()
      .add("boolean",true)))
  .build();

The second problem is accessing element in a JsonObject can be wordy; but it is relatively easy to knock up a method that would allow some simply XPath like accessor:

public static <T extends JsonValue> T get(JsonStructure structure, 
  String path, Class<T> type) {

  String segments[] = path.split("/");
  JsonValue currentValue = structure;
  for (String segment : segments) {

    if (segment.length() == 0) {
      continue;
    }

    if (currentValue instanceof JsonObject) {
      JsonObject currentObject = (JsonObject) currentValue;
      currentValue = currentObject.get(segment);
    } else if (currentValue instanceof JsonArray) {
      if (segment.startsWith("[") && segment.endsWith("]")) {
        int index = Integer.parseInt(segment.substring(1, segment.length() - 1));
        currentValue = ((JsonArray) currentValue).get(index);
      } else {
        throw new IllegalArgumentException("Array type requires key of the form [n]");
      }
    } else {
      throw new IllegalStateException("Value types are not decomposible" 
        + currentValue.getValueType());
    }

  }

  return type.cast(currentValue);

}


// Example to get hold of a string value

System.out.println(get(object, "/fish/child", JsonString.class));

Of course even this is a little bit untidy as you have to care about the internal JsonValue types which is a pain; and deal with possibly null pointers without the aid of Optional. It doesn't take much to wrap these up though.

public static String getString(JsonStructure structure, String path) {
  JsonString value = get(structure, path, JsonString.class);
  return value != null ? value.getString() : null;
}

public static boolean is(JsonStructure structure, String path) {
  JsonValue value = get(structure, path, JsonValue.class);
  return value != null ? value == JsonValue.TRUE : false;
}

public static boolean isNull(JsonStructure structure, String path) {
  JsonValue value = get(structure, path, JsonValue.class);
  return value != null ? value == JsonValue.NULL : false;
}

public static BigInteger getBigDecimal(JsonStructure structure, String path) {
  JsonNumber value = get(structure, path, JsonNumber.class);
  return value != null ? value.bigIntegerValue() : null;
}

public static int getInt(JsonStructure structure, String path) {
  JsonNumber value = get(structure, path, JsonNumber.class);
  return value != null ? value.intValue() : null;
}

public static JsonArray getArray(JsonStructure structure, String path) {
  return get(structure, path, JsonArray.class);
}

public static JsonObject getObject(JsonStructure structure, String path) {
  return get(structure, path, JsonObject.class);
}

This means you can write more direct code such as:

if (is(object, "/array/[2]/boolean")) {
  System.out.println(getString(object, "/fish/child"));
}
Sometimes it only take a few statically imported methods to make a API more useful / easier to read.

Learn more about Kotlin, a new programming language designed to solve problems that software developers face every day brought to you in partnership with JetBrains.

Topics:

Published at DZone with permission of Gerard Davison, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}