This module implements a JsonPath query engine for the java.util.json Java 21 backport. It parses JsonPath expressions into an AST and evaluates them against JSON documents.
Based on Stefan Goessner's JSONPath specification: https://goessner.net/articles/JsonPath/
JsonPath: Public API facade withquery()methodJsonPathAst: Sealed interface hierarchy defining the ASTJsonPathParser: Recursive descent parserJsonPathParseException: Parse error exception
JsonPathLoggingConfig: JUL test configuration base classJsonPathAstTest: Unit tests for AST recordsJsonPathParserTest: Unit tests for parserJsonPathGoessnerTest: Integration tests based on Goessner article examples
- Add new record type to
JsonPathAst.Segmentsealed interface - Update
JsonPathParserto parse the new syntax - Add parser tests in
JsonPathParserTest - Implement evaluation in
JsonPath.evaluateSegments() - Add integration tests in
JsonPathGoessnerTest
# Run all tests
$(command -v mvnd || command -v mvn || command -v ./mvnw) test -pl json-java21-jsonpath -Djava.util.logging.ConsoleHandler.level=INFO
# Run specific test class with debug logging
$(command -v mvnd || command -v mvn || command -v ./mvnw) test -pl json-java21-jsonpath -Dtest=JsonPathGoessnerTest -Djava.util.logging.ConsoleHandler.level=FINE
# Run single test method
$(command -v mvnd || command -v mvn || command -v ./mvnw) test -pl json-java21-jsonpath -Dtest=JsonPathGoessnerTest#testAuthorsOfAllBooks -Djava.util.logging.ConsoleHandler.level=FINEST- No external dependencies: Only java.base is allowed
- Pure TDD: Tests first, then implementation
- Functional style: Immutable records, pure evaluation functions
- Java 21 features: Records, sealed interfaces, pattern matching with switch
- Defensive copies: All collections in records are copied for immutability
- Script expressions: Only
@.length-1pattern is supported - No general expression evaluation: Complex scripts are not supported
- Stack-based recursion: May overflow on very deep documents
import jdk.sandbox.java.util.json.*;
import json.java21.jsonpath.JsonPath;
JsonValue json = Json.parse(jsonString);
// Preferred: parse once (cache) and reuse
JsonPath path = JsonPath.parse("$.store.book[*].author");
List<JsonValue> results = path.query(json);
// If you want a static call site, pass the compiled JsonPath
List<JsonValue> sameResults = JsonPath.query(path, json);Notes:
- Parsing a JsonPath expression is relatively expensive compared to evaluation; cache compiled
JsonPathinstances in hot code paths. JsonPath.query(String, JsonValue)is intended for one-off usage only.