JSON arrays are a fundamental data structure in JSON, used to store collections of values or objects. Java provides the JsonArray
and JsonArrayBuilder
classes from the Jakarta JSON API to efficiently create, manipulate, and parse JSON arrays. It also provides methods to parse a JSON Array into a Java Collection. In this tutorial we will see both options with practical examples
Introduction to JSON Arrays in Java
JSON (JavaScript Object Notation) arrays are a collection of values, ordered by index, and enclosed within square brackets []
. In Java, the Jakarta JSON API provides the JsonArray
and JsonArrayBuilder
classes to handle JSON arrays. On the other hand, you can use the getJsonArray
method of the JsonObject Class to parse a JSON Array into a Java Collection. Let’s see both options in detail.
Using JsonArrayBuilder
:
The JsonArrayBuilder
class provides a fluent API for constructing JSON arrays in a more concise manner. To create a new JsonArrayBuilder
, simply instantiate the class:
JsonArrayBuilder builder = new JsonArrayBuilder();
Then, you can add elements using various methods of this class. For example with the add method:
builder.add("Apple"); builder.add("Banana"); builder.add("Orange");
Once you’ve added all elements to the builder, you can convert it to a JsonArray instance using the build()
method:
JsonArray jsonArray = arrayBuilder.build();
Now that you have a grasp on the basics of this Class, let’s see a complete example which shows how to create a JSON Document which includes an Array of JSON Documents in it:
The following JBang Java Class contains the creation of the JSON Array and declares the required dependencies at the top of the script:
//usr/bin/env jbang "$0" "$@" ; exit $? //DEPS jakarta.json.bind:jakarta.json.bind-api:3.0.0 //DEPS org.eclipse:yasson:3.0.3 import jakarta.json.Json; import jakarta.json.JsonArray; import jakarta.json.JsonArrayBuilder; import jakarta.json.JsonObject; import jakarta.json.JsonObjectBuilder; public class JSONArrayExample { public static void main(String[] args) { // Create Order JSON object JsonObject order1 = createOrderJSON("1001", 500, "Model A"); JsonObject order2 = createOrderJSON("1002", 750, "Model B"); // Create Orders JSON array JsonArrayBuilder ordersArrayBuilder = Json.createArrayBuilder(); ordersArrayBuilder.add(order1); ordersArrayBuilder.add(order2); // Build the Orders JSON array JsonArray ordersArray = ordersArrayBuilder.build(); // Create Customer JSON object JsonObject customer = createCustomerJSON("John Doe", "123 Main St", ordersArray); // Print the Customer JSON object System.out.println("Customer JSON: " + customer); } // Method to create Order JSON object private static JsonObject createOrderJSON(String orderId, int price, String model) { JsonObjectBuilder orderBuilder = Json.createObjectBuilder(); orderBuilder.add("orderId", orderId); orderBuilder.add("price", price); orderBuilder.add("model", model); return orderBuilder.build(); } // Method to create Customer JSON object private static JsonObject createCustomerJSON(String name, String address, JsonArray orders) { JsonObjectBuilder customerBuilder = Json.createObjectBuilder(); customerBuilder.add("name", name); customerBuilder.add("address", address); customerBuilder.add("orders", orders); return customerBuilder.build(); } }
By running the script, you should be able to see the JSON text as output.
$ jbang JSONArrayExample.java Customer JSON: {"name":"John Doe","address":"123 Main St","orders":[{"orderId":"1001","price":500,"model":"Model A"},{"orderId":"1002","price":750,"model":"Model B"}]}
If you are new to JBang, you can head to this article for more information: JBang: Create Java scripts like a pro
Parsing a JSON Array to Java Collections
On the other hand, if you need to apply the reverse strategy, that is converting a JSON Array to a Java Collection, you can use the getJsonArray
method of the JsonObject Class. For example:
private static Customer parseCustomerFromJSON(String json) { try (JsonReader reader = Json.createReader(new StringReader(json))) { JsonObject customerObject = reader.readObject(); String name = customerObject.getString("name"); String address = customerObject.getString("address"); List<Order> orders = parseOrders(customerObject.getJsonArray("orders")); return new Customer(name, address, orders); } }
In the above example, we are parsing an array of Orders into the Order Java Class or Record. The full code follows here:
//usr/bin/env jbang "$0" "$@" ; exit $? //DEPS jakarta.json.bind:jakarta.json.bind-api:3.0.0 //DEPS org.eclipse:yasson:3.0.3 import jakarta.json.Json; import jakarta.json.JsonArray; import jakarta.json.JsonObject; import jakarta.json.JsonReader; import java.io.StringReader; import java.util.ArrayList; import java.util.List; public class JSONToJavaRecords { public static void main(String[] args) { // Simulated JSON data String jsonInput = "{\"name\":\"John Doe\",\"address\":\"123 Main St\",\"orders\":[{\"orderId\":\"1001\",\"price\":500,\"model\":\"Model A\"},{\"orderId\":\"1002\",\"price\":750,\"model\":\"Model B\"}]}"; // Convert JSON string to Java objects using Java Records Customer customer = parseCustomerFromJSON(jsonInput); // Display the parsed Java objects System.out.println("Customer Name: " + customer.name()); System.out.println("Customer Address: " + customer.address()); for (Order order : customer.orders()) { System.out.println("Order ID: " + order.orderId() + ", Price: " + order.price() + ", Model: " + order.model()); } } // Method to parse JSON into Customer Java Record private static Customer parseCustomerFromJSON(String json) { try (JsonReader reader = Json.createReader(new StringReader(json))) { JsonObject customerObject = reader.readObject(); String name = customerObject.getString("name"); String address = customerObject.getString("address"); List<Order> orders = parseOrders(customerObject.getJsonArray("orders")); return new Customer(name, address, orders); } } // Method to parse JSON array into List<Order> private static List<Order> parseOrders(JsonArray ordersArray) { List<Order> orders = new ArrayList<>(); for (JsonObject orderObject : ordersArray.getValuesAs(JsonObject.class)) { String orderId = orderObject.getString("orderId"); int price = orderObject.getInt("price"); String model = orderObject.getString("model"); orders.add(new Order(orderId, price, model)); } return orders; } // Define Java Records for Customer and Order record Customer(String name, String address, List<Order> orders) {} record Order(String orderId, int price, String model) {} }
You can run the Class and verify that it prints the Customer
Record, containing the List of Orders
:
$ jbang JSONToJavaRecords.java Customer Name: John Doe Customer Address: 123 Main St Order ID: 1001, Price: 500, Model: Model A Order ID: 1002, Price: 750, Model: Model B
Passing JSON Arrays in REST Services
JSON arrays are frequently used to represent collections of data in RESTful APIs. There are two main approaches to passing JSON arrays as parameters in REST services:
- Passing JSON Arrays in the Body as a POST Request: This approach is considered the preferred method for sending JSON data to a REST service. It ensures that the JSON data is properly formatted and avoids encoding issues.
To pass a JSON array in the body as a POST request, use the POST
method and set the Content-Type
header to application/json
. The JSON data should be in the request body.
For example, the following curl command sends a JSON array named fruits
containing the values "apple"
, "banana"
, and "grape"
to a REST service:
curl -X POST -H "Content-Type: application/json" -d '{"fruits": ["apple", "banana", "grape"]}' http://localhost:8080/myEndpoint
- Passing JSON Arrays as Parameters in the URL: This approach involves encoding the JSON array into a URL query parameter. While less common, it can be useful when the JSON array is relatively small.
To pass a JSON array as a parameter in the URL, use the @QueryParam
annotation in the REST service class. The JSON array should be encoded using the URLEncoder
class. For example:
@GET @Consumes({ MediaType.APPLICATION_JSON }) public String myMethod(@QueryParam("jsonArray") String jsonArray) throws Exception { // Decode the JSON array from the URL parameter String decodedJsonArray = URLDecoder.decode(jsonArray, "UTF-8"); // Parse the JSON array into a JsonArray object Customer customer = parseCustomerFromJSON(decodedJsonArray); ..... }
On the Client side, you should encode as well the JSON input parameter. For example, consider the following JSON:
{"name":"John Doe","address":"123 Main St","orders":[{"orderId":"1001","price":500,"model":"Model A"},{"orderId":"1002","price":750,"model":"Model B"}]}
It should be sent as follows:
curl http://localhost:8080/rest-demo/rest/hello?jsonArray="%7B%22name%22%3A%22John+Doe%22%2C%22address%22%3A%22123+Main+St%22%2C%22orders%22%3A%5B%7B%22orderId%22%3A%221001%22%2C%22price%22%3A500%2C%22model%22%3A%22Model+A%22%7D%2C%7B%22orderId%22%3A%221002%22%2C%22price%22%3A750%2C%22model%22%3A%22Model+B%22%7D%5D%7D"
Conclusion
Understanding and effectively using JSON arrays in Java via the Jakarta JSON API is crucial for handling structured data efficiently. The JsonArray
and JsonArrayBuilder
classes offer versatile tools for creating, manipulating, and parsing JSON arrays. In this tutorial we have also discussed the best options to pass a JSON Array as parameter in a REST Service.