JSON manipulation in Java 9 JShell image 101

JSON manipulation in Java 9 JShell

In this article I will demonstrate how we can work with JSON based data – for analysis, exploration, cleansing and processing – in JShell, much like we do in Python. I work with a JSON document with entries for all sessions at the Oracle OpenWorld 2017 conference (https://raw.githubusercontent.com/lucasjellema/scrape-oow17/master/oow2017-sessions-catalog.json)

The Java 9 SE specification for the JDK does not contain the JSON-P API and libraries for processing JSON. In order to work with JSON-P in JShell, we need to add the libraries – that we first need to find and download.

I have used a somewhat roundabout way to get hold of the required jar-files (but it works in a pretty straightforward manner):

1. Create a pom.xml file with dependencies on JSON-P

image

 

image

 

2. Then run

mvn install dependency:copy-dependencies

as described in this article: https://technology.amis.nl/2017/02/09/download-all-directly-and-indirectly-required-jar-files-using-maven-install-dependencycopy-dependencies/

this will download the relevant JAR files to subdirectory target/dependencies

image

3. Copy JAR files to a directory – that can be accessed from within the Docker container that runs JShell – for me that is the local lib directory that is mapped by Vagrant and Docker to /var/www/lib inside the Docker container that runs JShell.

 

4. In the container that runs JShell:

Start JShell with this statement that makes the new httpclient module available, for when the JSON document is retrieved from an HTTP URL resource:

jshell –add-modules jdk.incubator.httpclient

 

5. Update classpath from within jshell

To process JSON in JShell – using JSON-P – we need set the classpath to include the two jar files that were downloaded using Maven.

/env –class-path /var/www/lib/javax.json-1.1.jar:/var/www/lib/javax.json-api-1.1.jar

Then the classes in JSON-P are imported

import javax.json.*;

if we need to retrieve JSON data from a URL resource, we should also

import jdk.incubator.http.*;

 

6. I have made the JSON document available on the file system.

image

It can be accessed as follows:

InputStream input = new FileInputStream(“/var/www/oow2017-sessions-catalog.json”);

 

7. Parse data from file into JSON Document, get the root object and retrieve the array of sessions:

JsonReader jsonReader = Json.createReader(input)

JsonObject rootJSON = jsonReader.readObject();

JsonArray sessions = rootJSON.getJsonArray(“sessions”);

 

8. Filter sessions with the term SQL in the title and print their title to the System output – using Streams:

sessions.stream().map( p -> (JsonObject)p).filter(s ->  s.getString(“title”).contains(“SQL”)) .forEach( s -> {System.out.println(s.getString(“title”));})

image

 

One other example: show a list of all presentations for which a slidedeck has been made available for download along with the download URL:

sessions.stream()

.map( p -> (JsonObject)p)

.filter(s -> s.containsKey(“files”) && !s.isNull(“files”) && !(s.getJsonArray(“files”).isEmpty()))

.forEach( s -> {System.out.println(s.getString(“title”)+” url:”+s.getJsonArray(“files”).getJsonObject(0).getString(“url”));})

 

Bonus: Do HTTP Request

As an aside some steps in jshell to execute an HTTP request:

jshell> HttpClient client = HttpClient.newHttpClient();
client ==> jdk.incubator.http.HttpClientImpl@4d339552

jshell> HttpRequest request = HttpRequest.newBuilder(URI.create(“http://www.google.com”)).GET().build();
request ==> http://www.google.com GET

jshell> HttpResponse response = client.send(request, HttpResponse.BodyHandler.asString())
response ==> jdk.incubator.http.HttpResponseImpl@147ed70f

jshell> System.out.println(response.body())
<HTML><HEAD><meta http-equiv=”content-type” content=”text/html;charset=utf-8″>
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF=”http://www.google.nl/?gfe_rd=cr&amp;dcr=0&amp;ei=S2XeWcbPFpah4gTH6Lb4Ag”>here</A>.
</BODY></HTML>

 

image

One Response

  1. vchidrewar May 22, 2018