Rule(s)
- JSON is a data exchange format that has native support in JavaScript. Instead, the processing of JSON in Java relies on ad hoc external libraries.
- Java API for JSON Processing (a.k.a. JSON-P) is the “official” Oracle library. Competitors are discussed here… JSON-P is known as being part of Java Enterprise Edition -Java EE-. This situation may call for complicated installation and configuration because one may want to use JSON outside the (complex) world of Java EE. To avoid this, one has to download the JSON-P library as self-contained component from here…
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(); } } } }