A fast, minimal and simple JSON parser and writer.
It's not an object mapper, but a bare-bones library that aims at being
- lightweight: object representation with minimal memory footprint (e.g. no HashMaps)
- simple: reading, writing and modifying JSON with minimal code (short names, fluent style)
- fast: high performance comparable with other state-of-the-art parsers
- minimal: no dependencies, single package with just a few classes, small download size (< 35kB)
Getting started
Setup
To use icecore-json it must be available on your classpath.
You can use it as a dependency for your favorite build tool or download the latest version.
<dependency>
<groupId>com.arcticicestudio</groupId>
<artifactId>icecore-json</artifactId>
<version>0.8.0-frost.1</version>
</dependency>
compile(group: 'com.arcticicestudio', name: 'icecore-json', version: '0.8.0-frost.1')
<dependency org="com.arcticicestudio" name="icecore-json" rev="0.8.0-frost.1" />
Development snapshots are available via OSS Sonatype.
Build
Build and install icecore-json into your local repository without GPG signing:
mvn clean install
Signed artifacts may be build by using the sign-gpg
profile with a provided gpg.keyname
property:
mvn clean install -Dgpg.keyname=YourGPGKeyId
Continuous integration builds are running at Travis CI and Circle CI.
Usage Guide
This is a basic guide to show the common usage of the icecore-json API.
The API documentation can be found in the JavaDoc.
The class Json
is the entrypoint to the icecore-json API, use it to parse and to create JSON.
Parse JSON
You can parse JSON from a String
or from a java.io.Reader
.
You don't need to wrap your reader in a BufferedReader
, as the parse method uses a reading buffer.
JsonValue value = Json.parse(string);
JSON values
JSON values are represented by the type JsonValue
.
A JsonValue
can contain a JSON array, object, string, number, or one of the literals true
, false
, and null
.
To transform a JsonValue
into a Java type, use the methods asString
, asInt
, asFloat
, asArray
etc., depending on the expected type.
To query the actual type, use one of the methods isString
, isNumber
, isArray
, isObject
, isBoolean
, and isNull
.
if (value.isString()) {
String string = value.asString();
// ...
} else if (value.isArray()) {
JsonArray array = value.asArray();
// ...
}
JSON arrays
The method asArray
returns an instance of JsonArray
.
This subtype of JsonValue
provides a get
method to access the elements of a JSON array.
JsonArray array = Json.parse(reader).asArray();
String name = array.get(0).asString();
int quantity = array.get(1).asInt();
You can also iterate over the elements of a JsonArray
, which are again also JSON values:
for (JsonValue value : jsonArray) {
// ...
}
JSON objects
Similar to JsonArray
, the type JsonObject
represents JSON objects, the map type in JSON.
Members of a JSON object can be accessed by name using the get
method:
JsonObject object = Json.parse(input).asObject();
String name = object.get("name").asString();
int quantity = object.get("quantity").asInt();
There are also shorthand methods like getString
, getInt
, getDouble
, etc. that directly return the expected type.
These methods require a default value that is returned when the member is not found.
String name = object.getString("name", "Unknown");
int age = object.getInt("quantity", 1);
You can also iterate over the members of a JSON object:
for (Member member : jsonObject) {
String name = member.getName();
JsonValue value = member.getValue();
// ...
}
Example
This is a example on how to extract nested contents:
{
"order": 4378,
"items": [
{
"name": "Yogurt",
"id": "28469",
"quantity": 5
},
{
"name": "Coconut",
"id": "19875",
"quantity": 2
}
]
}
The following snippet extracts the names and quantities of all items:
JsonArray items = Json.parse(json).asObject().get("items").asArray();
for (JsonValue item : items) {
String name = item.asObject().getString("name", "Unknown Item");
int quantity = item.asObject().getInt("quantity", 1);
//..
}
Create JSON values
The entrypoint class Json
also has methods to create instances of JsonValue
from Java strings, numbers, and boolean values.
JsonValue name = Json.value("Yogurt");
JsonValue protein = Json.value(28);
And there are methods for creating empty arrays and objects as well.
Use these together with add
to create data structures.
JsonObject article = Json.object().add("name", "Yogurt").add("protein", 28);
// -> {"name": "Yogurt", "protein": 28}
JsonArray article = Json.array().add("Bob").add(16);
// -> ["Coconut", 16]
You can also create JSON arrays conveniently from Java arrays such as String[]
, int[]
, boolean[]
, etc.:
String[] javaNames = {"Yogurt", "Coconut"};
JsonArray jsonNames = Json.array(names);
Modify JSON arrays and objects
You can replace or remove array elements based on their index.
The index must be valid.
jsonArray.set(1, 24);
jsonArray.remove(1);
Likewise, members of JSON objects can be modified by their name.
If the name does not exist, set
will append a new member.
jsonObject.set("quantity", 12);
jsonObject.remove("quantity");
JsonObject
also provides a merge
method that copies all members from a given JSON object:
jsonObject.merge(otherObject);
Output JSON
The toString
method of a JsonValue
returns valid JSON strings.
You can also write to a java.io.Writer
using writeTo
:
String json = jsonValue.toString();
jsonValue.writeTo(writer);
Both methods accept an additonal parameter to enable formatted output.
String json = jsonValue.toString(WriterConfig.PRETTY_PRINT);
jsonValue.writeTo(writer, WriterConfig.PRETTY_PRINT);
Concurrency
The JSON structures in this library (JsonObject
and JsonArray
) are deliberately not thread-safe to keep them fast and simple.
In the rare case that JSON data structures must be accessed from multiple threads, while at least one of these threads modifies their contents, the application must ensure proper synchronization.
Iterators will throw a ConcurrentModificationException
when the contents of a JSON structure have been modified after the creation of the iterator.
Development
Contribution
Please report issues/bugs, feature requests and suggestions for improvements to the issue tracker.
Credits
The codebase of this project is inspired by the awesome minimal-json project.