Thursday, December 22, 2016

Parsing JSON using Jackson Library

Apart from being able to parse a json using the json libraries as shown here, another interesting way to parse a json is using the jackson library. To begin using this method, we add the following entry to our pom -

pom.xml

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.3</version>
</dependency>

And we use the following json file that we read from our resource folder -

sherlock.json

{
 "firstname": "Sherlock",
 "lastname": "Holmes",
 "address": {
  "street": "221B, Baker Street",
  "city": "London"
 },
 "books": ["A Study in Scarlet", "The Sign of the Four", "The Hound of the Baskervilles"]
}

The Jackson library essentially maps json elements to class variables. So, to map the values, a model consisting of one or more classes, having the same structure as the json is needed. For our current json, we need two classes - one for the original json and one for the address.

The two models are as follows -

Address.java


public class Address {
        String street;
        String city;

        //Getters and Setters
}

JsonEntry.java

import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;

public class JsonEntry {
        @JsonProperty("firstname")
        String firstName;

        @JsonProperty("lastname")
        String lastName;

        Address address;
        List<String> books;

        //Getters and Setters
}

The JsonProperty annotation is used when the name of the json field varies from the variable name. It is not needed in the case when the name of the field is the same as the name of the variable.

The complete java file which parses and prints the json is given below -

JsonParser.java

package json.parser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonParser {
 public static void main(String[] args) {
  String json;
  try {
   ClassLoader classLoader = JsonParser.class.getClassLoader();
   InputStream in = classLoader.getResourceAsStream("json/sherlock.json");
   json = convertToString(in);
   ObjectMapper mapper = new ObjectMapper();

   JsonEntry jsonParsed = parseJson(json, mapper);

   System.out.println("-----Printing Json--------------");
   printJson(jsonParsed);

   System.out.println("\n-----Pretty Printing Json--------------");
   prettyPrintJson(jsonParsed, mapper);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 private static String convertToString(InputStream in) throws IOException {
  StringBuilder sb = new StringBuilder();
  BufferedReader br = new BufferedReader(new InputStreamReader(in));

  String line;

  while ((line = br.readLine()) != null) {
   sb.append(line).append("\n");
  }

  return sb.toString();

 }

 private static JsonEntry parseJson(String jsonString, ObjectMapper mapper) {
  JsonEntry jsonEntry = null;

  try {
   // Convert JSON string to Object
   jsonEntry = mapper.readValue(jsonString, JsonEntry.class);
  } catch (JsonGenerationException e) {
   e.printStackTrace();
  } catch (JsonMappingException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }

  return jsonEntry;

 }

 private static void printJson(JsonEntry json) {
  System.out.println("First Name: " + json.getFirstName());
  System.out.println("Last Name: " + json.getLastName());

  System.out.println("Street: " + json.getAddress().getStreet());
  System.out.println("City: " + json.getAddress().getCity());

  for (int i = 0; i < json.getBooks().size(); i++) {
   System.out.println("Book " + (i + 1) + ": " + json.getBooks().get(i));
  }
 }

 private static void prettyPrintJson(JsonEntry json, ObjectMapper mapper) throws JsonProcessingException {
  String prettyPrint = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
  System.out.println(prettyPrint);
 }
}

The method parseJson() maps the json string to the object model definition. printJson() and prettyPrintJson()are simply outputting the values of the mapped json.


See also -
Parsing Json using Json Libraries

Parsing Json using Json Libraries

In this example we try to parse a json file using the json libraries. I have used the json library found here. So, I added the following dependency to my POM.

pom.xml

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20160810</version>
</dependency>

In my workspace, the follwing json file is used and read from the resource directory. The json can also be provided directly as a string or simply read from a file.

sherlock.json

{
 "firstname": "Sherlock",
 "lastname": "Holmes",
 "address": {
  "street": "221B, Baker Street",
  "city": "London"
 },
 "books": ["A Study in Scarlet", "The Sign of the Four", "The Hound of the Baskervilles"]
}


The code uses the class JSONObject and JSONArray to parse through the json and print accordingly. The code for the parser is as follows -


package json.reader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class JsonReader {
 public static void main(String[] args) {
  String json;
  try {
   ClassLoader classLoader = JsonReader.class.getClassLoader();
   InputStream in = classLoader.getResourceAsStream("json/sherlock.json");
   json = convertToString(in);

   parseJson(json);

  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 private static String convertToString(InputStream in) throws IOException {
  StringBuilder sb = new StringBuilder();
  BufferedReader br = new BufferedReader(new InputStreamReader(in));

  String line;

  while ((line = br.readLine()) != null) {
   sb.append(line).append("\n");
  }

  return sb.toString();

 }

 private static void parseJson(String jsonString) throws JSONException {
  JSONObject obj = new JSONObject(jsonString);

  System.out.println("First Name: " + obj.getString("firstname"));
  System.out.println("Last Name: " + obj.getString("lastname"));

  JSONObject address = obj.getJSONObject("address");
  System.out.println("Street: " + address.getString("street"));
  System.out.println("City: " + address.getString("city"));

  JSONArray books = obj.getJSONArray("books");
  for (int i = 0; i < books.length(); i++) {
   System.out.println("Book " + (i + 1) + ": " + books.get(i));
  }
 }
}

The responsibility of the method convertToString()is to take an InputStream as input and return the json as a string. The json string is then passed to the method parseJson() which reads throught the json one value at a time. The books is an array of string and hence is handled accordingly.

The output of the above program looks as below -

Output

First Name: Sherlock
Last Name: Holmes
Street: 221B, Baker Street
City: London
Book 1: A Study in Scarlet
Book 2: The Sign of the Four
Book 3: The Hound of the Baskervilles


See also -
Parsing JSON using Jackson Library