Processing JSON Data in Java

Let’s learn how we can parse JSON data in java applications. If you are devloping a java application, web or android app, at some point of time you will definately have to use Json data.

What is Json?

JSON stands for JavaScript Object Notation. It is a simple, light-weight data interchange format.

A simple JSON message look like this:

{
  "name": "simplejson",
  "version": "0.1.2",
  "description": "This is a simple JSON message",
  "className": "SimpleJson",
  "contributors": [
        "John Doe",
        "John Rabbit"
    ]
}

As you can see, the syntax is very simple, nestable, and really easy to understand.

http://json.org/ provides a concise summary of JSON syntax. There are two kinds of structure: JSON Objects (maps) and JSON Arrays (lists). JSON Objects are sets of name and value pairs, which can be represented either as a java.util.Map or as the properties of a Java object. For example, the fields of a LocalDate object for March 1, 2019 might be represented as:

{
        "year": 2019,
        "month": 3,
        "day" : 1
}

JSON Arrays are ordered lists, represented in Java either as arrays or as java.util.Lists. A list of two dates might look like this:

{
        [{
                "year": 2019,
                "month": 3,
                "day" : 1
        },{
                "year": 2019,
                "month": 4,
                "day" : 12
        }]
}

JSON is free-format, so the previous could also be written, with some loss of human-readability but no loss of information or functionality:

{[{"year":2019,"month":3,"day":1},{"year":2019,"month":4,"day":12}]}

Hundreds of parsers have, I’m sure, been written for JSON. A few that come to mind in the Java world include the following:

  1. Stringtree.org – very small and light-weight
  2. Json.org parser – widely used because it’s free and has a good domain name;
  3. Jackson.org parser – widely used because it’s very powerful, and used with Spring Framework
  4. Javax.json – Oracle’s new official but EE-only standard;

This article shows several ways of processing JSON data using some of the various APIs listed above. Disturbingly, the “official” javax.json API is only included in the Java EE, not the Java SE, so it is unlikely to see very much use on the client side. This API uses some names in common with the org.json API, but not enough to be consdered “compatible”.

As this is a tutorial for client-side Java developers, nothing will be made of the ability to process JSON directly in server-generated browser-based JavaScript, though this can be very useful in building enterprise applications.

Generating JSON directly

Problem

You want to generate JSON without bothering to use an API.

Solution

Get the data you want, and use println() or String.format() as appropriate.

There is nothing the APIs do that you can’t do yourself. For the utterly trivial cases, you can just use the PrintWriter.println() or String.format()

This code prints the year, month, and date from a LocalTime object. Some of the JSON formatting is delegated to the toJson() object.

public class LocalDateToJsonManually {
    private static final String OPEN = "{";
    private static final String CLOSE = "}";
    public static void main(String[] args) {
        LocalDate dNow = LocalDate.now();
        System.out.println(toJson(dNow));
    }
    public static String toJson(LocalDate dNow) {
        StringBuilder sb = new StringBuilder();
        sb.append(OPEN).append("\n");
        sb.append(jsonize("year", dNow.getYear()));
        sb.append(jsonize("month", dNow.getMonth()));
        sb.append(jsonize("day", dNow.getDayOfMonth()));
        sb.append(CLOSE).append("\n");
        return sb.toString();
    }
    public static String jsonize(String key, Object value) {
        return String.format("\"%s\": \"%s\",\n", key, value);
    }
}

Of course, this is an extremely trivial example. For anything more involved, or for the common case of having to parse JSON objects, using one of the frameworks will be easier on your nerves.

Parsing and Writing JSON with Jackson

Problem

You want to read and/or write JSON using a full-function JSON API.

Solution

Use Jackson, the full-blown JSON API.

Jackson provides many ways of working. For simple cases, you can have POJO (plain old Java objects) converted to/from JSON more-or-less automatically

public class ReadWriteJackson {
    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();         1
        String jsonInput =                                                      2
                "{\"id\":0,\"firstName\":\"John\",\"lastName\":\"Doe\"}";
        Person q = mapper.readValue(jsonInput, Person.class);
        System.out.println("Read and parsed Person from JSON: " + q);
        Person p = new Person("John", "Rabbit");                 3
        System.out.print("Person object " + p +" as JSON = ");
        mapper.writeValue(System.out, p);
    }
}
  1. Create a Jackson ObjectMapper which can map POJOs to/from JSON.
  2. Map the string jsonInput into a Person object with one call to readValue()
  3. Convert the Person object p into JSON with one call to writeValue()

Running this example produces the following output:

Read and parsed Person from JSON: John Doe
Person object John Rabbit as JSON = {"id":0,"firstName":"John",
        "lastName":"Rabbit","name":"John Rabbit"}

As another example, this code reads the “parser description” example file which opened this chapter; notice the declaration List<String> for the array of contributors.

public class SoftwareParseJackson {
    final static String FILE_NAME = "/json/softwareinfo.json";
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        InputStream jsonInput = SoftwareParseJackson.class.getResourceAsStream(FILE_NAME);
        if (jsonInput == null) {
            throw new NullPointerException("can't find" + FILE_NAME);
        }
        SoftwareInfo sware = mapper.readValue(jsonInput, SoftwareInfo.class);
        System.out.println(sware);
    }
}

Running this example produces the following output:

Software: simplejson (0.1.2) by [John Doe, John Rabbit]

Of course there are cases where the mapping gets more involved, for this purpose Jackson provides a set of annotations to control the mapping. But the default mapping is pretty good!

Parsing and Writing JSON with org.json

Problem

You want to read/write JSON using a mid-sized, widely-used JSON API.

Solution

Consider using org.json API; it’s widely used and is also used in Android.

The org.json package is not as advanced as Jackon, nor as high-level; it makes you think and work in terms of the underlying JSON abstractions instead of at the Java code level.

public class SoftwareParseOrgJson {
    final static String FILE_NAME = "/json/softwareinfo.json";
    public static void main(String[] args) throws Exception {
        InputStream jsonInput = SoftwareParseOrgJson.class.getResourceAsStream(FILE_NAME);
        if (jsonInput == null) {
            throw new NullPointerException("can't find" + FILE_NAME);
        }
        JSONObject obj = new JSONObject(new JSONTokener(jsonInput));  1
        System.out.println("Software Name: " + obj.getString("name"));     2
        System.out.println("Version: " + obj.getString("version"));
        System.out.println("Description: " + obj.getString("description"));
        System.out.println("Class: " + obj.getString("className"));
        JSONArray contribs = obj.getJSONArray("contributors");                 3
        for (int i = 0; i < contribs.length(); i++) {                                     4
            System.out.println("Contributor Name: " + contribs.get(i));
        }
    }
}

Running it does produce the expected output:

Software Name: simplejson
Version: 0.1.2
Description: This is a simple JSON message
Class: SimpleJson
Contributor Name: John Doe
Contributor Name: John Rabbit

JSONObject and JSONArray use their toString() method to produce (correctly-formatted) JSON strings. For example:

public class WriteOrgJson {
    public static void main(String[] args) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Name", "simplejson").         1
            put("Version", "0.1.2").
            put("Class", "SimpleJson");
        String printable = jsonObject.toString();     2
        System.out.println(printable);
    }
}

Running this produces the following:

{"Name":"simplejson","Class":"SimpleJson","Version":"0.1.2"}

Summary

Many APIs exist for Java. Jackson is the biggest and most powerful; org.json and javax.json are in the middle; StringTree is the smallest. For a list of these and other JSON APIs, consult http://www.json.org/java/ and scroll past the syntax summary.

Muhammad Mubeen

Muhammad Mubeen

Mubeen is a full-stack web & mobile app developer who is very proficient in MEAN.js, Vue, Python, Ionic 4, Flutter, Firebase, ROR, and PHP. He has created multiple mobile and web applications. He is very passionate about sharing his knowledge.

Leave a Reply

Your email address will not be published. Required fields are marked *

Trending