JSON Small and Fast Parser - A lightweight, high-performance JSON processing library for Java
—
JSONNavi provides a jQuery-like API for dynamically traversing and manipulating JSON structures without requiring predefined types. It's particularly useful for working with unknown or complex JSON schemas.
JSONNavi allows you to:
public static JSONNavi<JSONAwareEx> newInstance();
public static JSONNavi<JSONObject> newInstanceObject();
public static JSONNavi<JSONArray> newInstanceArray();Create new JSONNavi instances for different root types.
// Generic navigator (can hold any JSON type)
JSONNavi<JSONAwareEx> nav = JSONNavi.newInstance();
// Object-specific navigator
JSONNavi<JSONObject> objNav = JSONNavi.newInstanceObject();
// Array-specific navigator
JSONNavi<JSONArray> arrNav = JSONNavi.newInstanceArray();public JSONNavi(JsonReaderI<? super T> mapper);
public JSONNavi(String json);
public JSONNavi(String json, JsonReaderI<T> mapper);
public JSONNavi(String json, Class<T> mapTo);Create navigators from JSON strings with optional custom parsing.
// Parse JSON string and navigate
JSONNavi<?> nav = new JSONNavi<>("{\"user\": {\"name\": \"John\", \"age\": 30}}");
// Parse with custom mapper
JSONNavi<MyUser> userNav = new JSONNavi<>(jsonString, MyUser.class);
// Parse with custom reader
JSONNavi<JSONObject> objNav = new JSONNavi<>(jsonString, new CustomJsonReader());public JSONNavi<T> root();
public JSONNavi<?> at(String key);
public JSONNavi<?> at(int index);
public JSONNavi<?> atNext();
public JSONNavi<?> up();
public JSONNavi<?> up(int level);Navigate through JSON structures.
String json = """
{
"users": [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30}
],
"metadata": {"total": 2}
}
""";
JSONNavi<?> nav = new JSONNavi<>(json);
// Navigate to nested values
String firstUserName = nav.at("users").at(0).at("name").asString(); // "Alice"
int total = nav.root().at("metadata").at("total").asInt(); // 2
// Navigate through arrays
int bobAge = nav.root().at("users").at(1).at("age").asInt(); // 30
// Move up in hierarchy
JSONNavi<?> usersArray = nav.root().at("users").at(0).up(); // back to users array
JSONNavi<?> rootAgain = nav.at("users").up(); // back to root objectString arrayJson = "[\"apple\", \"banana\", \"cherry\", \"date\"]";
JSONNavi<?> nav = new JSONNavi<>(arrayJson);
// Navigate by index
String first = nav.at(0).asString(); // "apple"
String third = nav.root().at(2).asString(); // "cherry"
// Navigate to next positions
JSONNavi<?> current = nav.at(0);
String second = current.atNext().asString(); // "banana"
String fourth = current.atNext().asString(); // "cherry"
String fifth = current.atNext().asString(); // "date"public boolean hasFailure();
public Object getCurrentObject();
public boolean isArray();
public boolean isObject();
public boolean hasKey(String key);
public int getSize();
public Collection<String> getKeys();Inspect current navigation state and JSON structure.
JSONNavi<?> nav = new JSONNavi<>("{\"users\": [{\"name\": \"Alice\"}], \"count\": 1}");
// Check navigation state
boolean failed = nav.at("nonexistent").hasFailure(); // true
boolean success = nav.root().at("users").hasFailure(); // false
// Inspect current position
nav.at("users");
boolean isArr = nav.isArray(); // true
boolean isObj = nav.isObject(); // false
int size = nav.getSize(); // 1
nav.root();
boolean hasUsers = nav.hasKey("users"); // true
boolean hasEmail = nav.hasKey("email"); // false
Collection<String> keys = nav.getKeys(); // ["users", "count"]
// Get current object
Object current = nav.at("users").getCurrentObject(); // JSONArray instance
Object userObj = nav.at(0).getCurrentObject(); // JSONObject instancepublic Object get(String key);
public Object get(int index);
public String getString(String key);
public int getInt(String key);
public Integer getInteger(String key);
public double getDouble(String key);Access values from current position without navigation.
String json = """
{
"user": {
"name": "John",
"age": 30,
"salary": 75000.50,
"active": true
}
}
""";
JSONNavi<?> nav = new JSONNavi<>(json).at("user");
// Direct access from current position
String name = nav.getString("name"); // "John"
int age = nav.getInt("age"); // 30
double salary = nav.getDouble("salary"); // 75000.50
Object active = nav.get("active"); // Boolean true
// Type-safe access
Integer ageObj = nav.getInteger("age"); // Integer 30
Integer missing = nav.getInteger("missing"); // nullpublic String asString();
public int asInt();
public Integer asIntegerObj();
public long asLong();
public Long asLongObj();
public double asDouble();
public Double asDoubleObj();
public float asFloat();
public Float asFloatObj();
public boolean asBoolean();
public Boolean asBooleanObj();Convert current navigation position to specific types.
JSONNavi<?> nav = new JSONNavi<>("[42, \"123\", true, 3.14, null]");
// Navigate and convert
int num1 = nav.at(0).asInt(); // 42
int num2 = nav.root().at(1).asInt(); // 123 (string converted to int)
boolean bool = nav.root().at(2).asBoolean(); // true
double decimal = nav.root().at(3).asDouble(); // 3.14
// Safe conversion with objects (returns null for invalid/null values)
Integer nullValue = nav.root().at(4).asIntegerObj(); // null
Boolean validBool = nav.root().at(2).asBooleanObj(); // Boolean.TRUEpublic JSONNavi<T> object();
public JSONNavi<T> array();Create objects or arrays at current position.
JSONNavi<JSONAwareEx> nav = JSONNavi.newInstance();
// Create nested structure
nav.object() // Create root object
.at("users").array() // Create users array
.at(0).object() // Create first user object
.set("name", "Alice")
.set("age", 25);
String result = nav.toString();
// {"users":[{"name":"Alice","age":25}]}public JSONNavi<T> set(String key, String value);
public JSONNavi<T> set(String key, Number value);
public JSONNavi<T> set(String key, int value);
public JSONNavi<T> set(String key, long value);
public JSONNavi<T> set(String key, double value);
public JSONNavi<T> set(String key, float value);
public JSONNavi<T> set(String text);
public JSONNavi<T> set(Number num);
public JSONNavi<T> set(Boolean bool);Set values at current position or by key.
JSONNavi<JSONAwareEx> nav = JSONNavi.newInstance();
// Create and populate object
nav.object()
.set("name", "John Doe")
.set("age", 30)
.set("salary", 75000.50)
.set("active", true);
// Navigate and update
nav.at("name").set("John Smith"); // Update existing value
nav.root().set("department", "Engineering"); // Add new field
String json = nav.toString();
// {"name":"John Smith","age":30,"salary":75000.5,"active":true,"department":"Engineering"}public JSONNavi<T> add(Object... values);Add values to arrays.
JSONNavi<JSONAwareEx> nav = JSONNavi.newInstance();
// Create array and add elements
nav.array()
.add("apple", "banana", "cherry")
.add(42)
.add(true);
String json = nav.toString();
// ["apple","banana","cherry",42,true]
// Add to existing arrays
JSONNavi<?> existing = new JSONNavi<>("[1, 2, 3]");
existing.add(4, 5, 6);
String updated = existing.toString(); // [1,2,3,4,5,6]public T getRoot();
public String getJPath();
public String toString();
public String toString(JSONStyle compression);Access root object and debugging information.
JSONNavi<?> nav = new JSONNavi<>("{\"a\": {\"b\": [1, 2, {\"c\": \"value\"}]}}");
// Navigate deep
nav.at("a").at("b").at(2).at("c");
// Get path information
String path = nav.getJPath(); // $.a.b[2].c
// Get root object
Object root = nav.getRoot(); // Original JSONObject
// Serialize current state
String json = nav.toString(); // "value" (current position)
String rootJson = nav.root().toString(); // Full JSON structure// Unknown JSON structure
String unknownJson = """
{
"data": {
"users": [
{"id": 1, "profile": {"name": "Alice", "email": "alice@example.com"}},
{"id": 2, "profile": {"name": "Bob", "email": "bob@example.com"}}
],
"pagination": {"page": 1, "total": 2}
}
}
""";
JSONNavi<?> nav = new JSONNavi<>(unknownJson);
// Explore structure
if (nav.at("data").hasKey("users")) {
int userCount = nav.at("users").getSize();
System.out.println("Found " + userCount + " users");
// Process each user
for (int i = 0; i < userCount; i++) {
JSONNavi<?> user = nav.at(i);
if (user.hasKey("profile")) {
String name = user.at("profile").getString("name");
String email = user.at("profile").getString("email");
System.out.println("User: " + name + " (" + email + ")");
}
nav.up(); // Back to users array
}
}// Build complex JSON structure dynamically
JSONNavi<JSONAwareEx> nav = JSONNavi.newInstance();
nav.object()
.set("apiVersion", "v1")
.set("timestamp", System.currentTimeMillis())
.at("users").array();
// Add users dynamically
String[] names = {"Alice", "Bob", "Charlie"};
int[] ages = {25, 30, 35};
for (int i = 0; i < names.length; i++) {
nav.at(i).object()
.set("id", i + 1)
.set("name", names[i])
.set("age", ages[i])
.at("roles").array()
.add("user");
if (ages[i] > 30) {
nav.add("senior");
}
nav.up().up(); // Back to users array
}
// Add metadata
nav.root()
.at("metadata").object()
.set("userCount", names.length)
.set("generated", true);
String result = nav.toString();String json = "{\"user\": {\"profile\": {\"name\": \"John\"}}}";
JSONNavi<?> nav = new JSONNavi<>(json);
// Chain navigation with error checking
String name = null;
if (!nav.at("user").hasFailure() &&
!nav.at("profile").hasFailure() &&
!nav.at("name").hasFailure()) {
name = nav.asString();
}
// Alternative: check at each step
nav.root();
if (nav.hasKey("user")) {
nav.at("user");
if (nav.hasKey("profile")) {
nav.at("profile");
name = nav.getString("name");
}
}
// Or use try-catch approach
try {
String safeName = nav.root().at("user").at("profile").at("name").asString();
} catch (Exception e) {
// Handle navigation failure
System.out.println("Failed to get user name: " + e.getMessage());
}String arrayJson = """
[
{"name": "Alice", "score": 95, "active": true},
{"name": "Bob", "score": 87, "active": false},
{"name": "Charlie", "score": 92, "active": true}
]
""";
JSONNavi<?> nav = new JSONNavi<>(arrayJson);
// Process array elements
int size = nav.getSize();
JSONArray activeUsers = new JSONArray();
for (int i = 0; i < size; i++) {
JSONNavi<?> user = nav.at(i);
boolean active = user.getBoolean("active");
if (active) {
String name = user.getString("name");
int score = user.getInt("score");
JSONObject activeUser = new JSONObject()
.appendField("name", name)
.appendField("score", score);
activeUsers.appendElement(activeUser);
}
nav.up(); // Back to root array
}
String activeUsersJson = JSONValue.toJSONString(activeUsers);JSONNavi<?> nav = new JSONNavi<>("{\"users\": [], \"settings\": {}}");
// Conditionally modify structure
nav.at("users");
if (nav.getSize() == 0) {
// Add default user if array is empty
nav.add(new JSONObject()
.appendField("name", "Default User")
.appendField("role", "guest"));
}
nav.root().at("settings");
if (!nav.hasKey("theme")) {
nav.set("theme", "light");
}
if (!nav.hasKey("notifications")) {
nav.set("notifications", true);
}
String updated = nav.root().toString();Install with Tessl CLI
npx tessl i tessl/maven-net-minidev--json-smart