Java Processing of JavaScript Object Notation (JSON)


Creative Commons License
This -Java Processing of JavaScript Object Notation (JSON)- tutorial is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License
JavaScript Object Notation (JSON)

Rule(s)

Scenario(s)

Open Exchange Rates is a professional currency conversion service (paying service with free simplified version). Service consumption is based on JSON as shown in the following example.

Example Currency_conversion.Java.zip  (connection to the service)

/**
* Currency exchange rate has a default base, which is 'USD'. For
* simplification, 'fromCurrency' is not used
*/
public static double convert(String licenseKey, /* String fromCurrency, */ String toCurrency, double amount) throws java.net.MalformedURLException, java.io.IOException {
    java.net.URL url = new java.net.URL("http://openexchangerates.org/api/latest.json" + "?app_id=" + licenseKey); // Subscription to the service is mandatory to get a license key!
    java.net.URLConnection connection = (java.net.URLConnection) url.openConnection();
    javax.json.stream.JsonParserFactory factory = javax.json.Json.createParserFactory(null);
    // Effective connection with the service:
    javax.json.stream.JsonParser parser = factory.createParser(connection.getInputStream());
    (…)

Example Currency_conversion.Java.zip  (get data from JSON processing)

   (…)
    while (parser.hasNext()) {
        javax.json.stream.JsonParser.Event event = parser.next();
        if (event == javax.json.stream.JsonParser.Event.KEY_NAME && parser.getString().equals(toCurrency)) {
            while (parser.hasNext()) {
                event = parser.next();
                if (event == javax.json.stream.JsonParser.Event.VALUE_NUMBER) {
                    amount *= parser.getBigDecimal().doubleValue();
                    break;
                }
            }
        }
    }
    return amount;
}

Scenario(s)

Carrefour.io is the digital vision of the Carrefour French retailer. Carrefour.io offers the Items the Stores APIs. Queries about items (i.e., common consumer products) return JSON raw data that may require post-processing as in the following example.

A similar scenario is developed here… based on the Async Http Client library. However, please note that, since Java 11, HTTP-based requests are totally asynchronous (further detail here…) using the java.util.concurrent.CompletableFuture<T> class.

Example Carrefour_Items.Java.zip  (first, connection to the service by means of the OkHttp library)

private void _get_items_(java.time.Duration time_out) { // OkHttp library: http://square.github.io/okhttp/
    assert (!time_out.isNegative() && !time_out.isZero());
    if (_json_query != null && _json_result == null) {
        _get_items_elapsed_time = System.currentTimeMillis();
        okhttp3.OkHttpClient.Builder builder = new okhttp3.OkHttpClient.Builder();
        builder.connectTimeout(time_out);
        builder.readTimeout(time_out);
        // builder.writeTimeout(time_out);
        okhttp3.OkHttpClient client = builder.build();

        okhttp3.Request request = new okhttp3.Request.Builder()
            .url(_url) // ' private final static String _url = "https://api.fr.carrefour.io/v1/openapi/items";'
            .post(okhttp3.RequestBody.create(okhttp3.MediaType.parse("application/json"), _json_query))
            .addHeader("accept", "application/json")
            .addHeader("content-type", "application/json")
            .addHeader("x-ibm-client-id", _x_ibm_client_id)
            .addHeader("x-ibm-client-secret", _x_ibm_client_secret)
            .build();
        try (okhttp3.Response response = client.newCall(request).execute()) {
            java.io.InputStream is = response.body().source().inputStream();
            _result_as_pretty_JSON(is); // Versus '_result_as_raw_JSON(is);'
            // 'close' is guaranteed by try-with-resource(s)
        } catch (java.io.IOException ioe) {
             _json_result = javax.json.Json.createObjectBuilder().add(_ERROR, ioe.getMessage()).build().toString();
            System.err.println(ioe.getClass().getSimpleName() + ": " + ioe.getMessage());
        } finally {
             _get_items_elapsed_time = System.currentTimeMillis() - _get_items_elapsed_time;
        }
    }
}

Example Carrefour_Items.Java.zip  (next, transform raw JSON data into indented format)

private void _result_as_pretty_JSON(java.io.InputStream is) /*throws java.io.IOException*/ {
//        assert (is != null && is.available() == 0); // Official Java doc.: 'The available method for class InputStream always returns 0.'
        java.util.Map<String, Boolean> properties = new java.util.HashMap<>();
        properties.put(javax.json.stream.JsonGenerator.PRETTY_PRINTING, true);
        java.io.StringWriter sw = new java.io.StringWriter();
        try (javax.json.JsonWriter jw = javax.json.Json.createWriterFactory(properties).createWriter(sw)) {
            jw.writeObject(javax.json.Json.createReader(is).readObject());
            // 'close' is guaranteed by try-with-resource(s)
        }
        _json_result = sw.toString();
        _counted_items = -1L; // Error
        try (javax.json.stream.JsonParser parser = javax.json.Json.createParser(new java.io.StringReader(_json_result))) {
            while (parser.hasNext()) {
                // '_LIST' key is associated with a value being an array whose elements are the returned items (by default, only 20 are returned):
                if (parser.next() == javax.json.stream.JsonParser.Event.KEY_NAME && parser.getString().equals(_LIST)) {
                    final javax.json.stream.JsonParser.Event event = parser.next();
                    assert (event == javax.json.stream.JsonParser.Event.START_ARRAY);
                    _counted_items = parser.getArray().size();
                }
            }
        }
    }