How to use JSON-P to create and parse JSON in Java

This tutorial shows how to use JSON Processing (JSR-353) API, part of the Jakarta EE specification. In general terms, there are two main APIs to handle JSON in Java:

  • JSON-P (JSON-Processing, JSR 374): Specifies a very low-level processing library which can be carried out with two models for JSON processing: the Object Model API and the Streaming API.
  • JSON-B (JSON-Binding, JSR 367): Provides a binding layer on top of JSON-P, making it easier to convert objects to and from JSON.

If you want an overview on both API, we recommend checking this tutorial: How to parse JSON in Java

Getting started with JSON Processing API

JSON-P is split into two core APIs, the Streaming API (javax.json.stream), and the JSON Object Model API (javax.json).

  • The Streaming API is used to parse (JsonParser) and generate JSON data (JsonGenerator).
  • The Object Model API, which is a simple, easy to use API implemented on top of the Streaming API. It creates an in-memory tree-like structure of the JSON data.

Firstly, let’s see a basic example which encodes some JSON data in various format:

package com.sample;

import java.io.IOException;
import javax.json.Json;
import javax.json.stream.JsonGenerator;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
@WebServlet("/json")
public class HelloWorldJson extends HttpServlet {

    @Override
    protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/json");
        final JsonGenerator generator = Json.createGenerator(response.getWriter());
       
        generator.writeStartObject();
        generator.write("Hello", "World");
        generator.write("Balance", new Double(1000));
        generator.write("IsMember", new Boolean(true));
        generator.writeEnd();
        generator.close();
    }
}

As you can see, this class uses the JsonGenerator to define a Json object and write it to the Servlet’s response stream. All you need in order to compile your javax.json.* classes is the jakarta.jakartaee-api dependency in place:

<dependency>
     <groupId>jakarta.platform</groupId>
     <artifactId>jakarta.jakartaee-api</artifactId>
     <version>8.0.0</version>
     <scope>provided</scope>
</dependency>

Testing the example

Let’s see the output using the cool SoapUI REST tester (if you don’t have it installed a Browser will be just enough):

json tutorial wildfly json-p java ee 7 json tutorial wildfly json-p java ee 7

Using JsonObjectBuilder

In the second example we are using the JsonObjectBuilder to generate a more complex JsonObject. A JsonObject class represents an immutable JSON object value containing a map view to the JSON object name/value mappings.

package com.sample;

import java.io.IOException;
import java.io.StringWriter;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonWriter;
import javax.json.stream.JsonGenerator;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/json2")
public class HelloWorldJson2 extends HttpServlet {

    @Override
    protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/json");
       
        JsonWriter jsonWriter = Json.createWriter(response.getWriter());
        JsonObject model = Json.createObjectBuilder()
                   .add("firstName", "johnny")
                   .add("lastName", "English")
                   .add("age", 48)
                   .add("streetAddress", "Downing Street 10")
                   .add("city", "London")
                   .add("state", "UK")
                   .add("phoneNumbers", Json.createArrayBuilder()
                      .add(Json.createObjectBuilder()
                         .add("type", "mobile")
                         .add("number", "338-111-1111"))
                      .add(Json.createObjectBuilder()
                         .add("type", "home")
                         .add("number", "0771-222-2222")))
                   .build();
        
        jsonWriter.writeObject(model);
        jsonWriter.close();
     
        jsonWriter.close();
    }
}

To create these object models, you can use the builder pattern (JsonObjectBuilder or JsonArrayBuilder) or read them from an input source (InputStream or Reader) using JsonReader. You can then write these object models to an output source (OutputStream or Writer) using the JsonWriter.

Done with object streaming, let’s see how to parse out examples. For this purpose we will use the JsonParser interface which provides read-only access to JSON data in a streaming way. This is the most efficient way for reading JSON data. The class Json contains methods to create parsers from input sources (InputStream and Reader).
The following example demonstrates how to create a parser from a StringReader which contains the JSON String:

package com.sample;

import java.io.StringReader;

import javax.json.Json;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;

import org.junit.Test;

import com.sample.helper.ClientGet;

public class Tester {

    @Test
    public void test() {
        String result = ClientGet.get("http://localhost:8080/json/json");
        final JsonParser parser = Json.createParser(new StringReader(result));
        String key = null;
        String value = null;
        while (parser.hasNext()) {
            final Event event = parser.next();
            switch (event) {
                case KEY_NAME:
                    key = parser.getString();
                    System.out.println(key);
                    break;
                case VALUE_STRING:
                    value = parser.getString();
                    System.out.println(value);
                    break;
            }
        }
        parser.close();
    }

}

Finally, here’s the output from executing mvn test, which shows the key-value pairs for the first example:

Output from Server ....

Hello
World
Balance
IsMember

The source code for this tutorial is available here: https://github.com/fmarchioni/mastertheboss/tree/master/json/jsonp-demo

Using a different JSON Implementation

JSON-P is a standard Jakarta EE project, therefore the application server will try to run its implementation available as a module in jakarta.json-api-1.x.x.jar. if you want to switch to a different JSON implementation, you have to exclude the JSON API using the jboss-deployment-structure.xml file.

Here is an example:

<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <deployment>
  <exclusions>
    <module name="javax.json.bind.api"/>
    <module name="javax.json.api"/>
  </exclusions>
  </deployment>
</jboss-deployment-structure>
Found the article helpful? if so please follow us on Socials