在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:wanglingsong/JsonSurfer开源软件地址:https://github.com/wanglingsong/JsonSurfer开源编程语言:Java 99.5%开源软件介绍:JsonSurfer - Let's surf on Json!Why JsonSurfer
Getting startedWhat is JsonPath?
JsonSurfer has drivers for most of popular json libraries including: Gson, Jackson, FastJson and JsonSimple. Choose one and add to your POM. <dependency>
<groupId>com.github.jsurfer</groupId>
<artifactId>jsurfer-gson</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>com.github.jsurfer</groupId>
<artifactId>jsurfer-jackson</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>com.github.jsurfer</groupId>
<artifactId>jsurfer-fastjson</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>com.github.jsurfer</groupId>
<artifactId>jsurfer-jsonsimple</artifactId>
<version>1.6.3</version>
</dependency>
Usage:Create your JsonSurfer:
// use gson parser and use gson provider use to deserialize json into gson model i.e.com.google.gson.JsonElement
JsonSurfer surfer = new JsonSurfer(GsonParser.INSTANCE, GsonProvider.INSTANCE); or JsonSurfer surfer = JsonSurferGson.INSTANCE;
JsonSurfer surfer = new JsonSurfer(JacksonParser.INSTANCE, JacksonProvider.INSTANCE); or JsonSurfer surfer = JsonSurferJackson.INSTANCE;
// use json-simple parser and json-simple provider to deserialize json into json-simple model i.e.org.json.simple.JSONObject or org.json.simple.JSONArray
JsonSurfer surfer = new JsonSurfer(JsonSimpleParser.INSTANCE, JsonSimpleProvider.INSTANCE); or JsonSurfer surfer = JsonSurferJsonSimple.INSTANCE;
JsonSurfer surfer = new JsonSurfer(FastJsonParser.INSTANCE, FastJsonProvider.INSTANCE); or JsonSurfer surfer = JsonSurferFastJson.INSTANCE; Collect value by JsonPath Collector collector = surfer.collector(sample);
ValueBox<String> box1 = collector.collectOne("$.store.book[1].category", String.class);
ValueBox<Object> box2 = collector.collectOne("$.store.book[2].isbn");
ValueBox<Collection<Object>> box3 = collector.collectAll("$.store.book[*]");
collector.exec(); // make sure exec() invoked before getting value from boxes
box1.get();
box2.get();
box3.get(); 【DEPRECATED】 Collect the first matched value and stop immediately JsonSurfer jsonSurfer = JsonSurferGson.INSTANCE;
Object singleResult = jsonSurfer.collectOne(sample, "$.store.book[0]"); 【DEPRECATED】 Colllect every matched value into a collection JsonSurfer jsonSurfer = JsonSurferGson.INSTANCE;
Collection<Object> multipleResults = jsonSurfer.collectAll(sample, "$.store.book[*]"); "Surfing" in Json and collecting matched value in the listeners JsonSurfer surfer = JsonSurferGson.INSTANCE;
surfer.configBuilder()
.bind("$.store.book[*]", new JsonPathListener() {
@Override
public void onValue(Object value, ParsingContext context) {
System.out.println(value);
}
})
.buildAndSurf(sample); Reuse listener binding.SurfingConfiguration is thread-safe as long as your listeners are stateless. JsonSurfer surfer = JsonSurferGson.INSTANCE;
SurfingConfiguration config = surfer.configBuilder()
.bind("$.store.book[*]", new JsonPathListener() {
@Override
public void onValue(Object value, ParsingContext context) {
System.out.println(value);
}
})
.build();
surfer.surf(sample1, config);
surfer.surf(sample2, config); Compiled JsonPathJsonPath object is immutable and can be reused safely. Tips: Most of JsonSurfer API have two version: accepting raw JsonPath string or JsonPath object. The latter is always faster than the former without compiling JsonPath. JsonPath compiledPath = JsonPathCompiler.compile("$..book[1,3]['author','title']");
String value = surfer.collectOne(read("sample.json"), String.class, compiledPath); JsonPath Filters
You can use logical operators '&&' and '||' to create more complex filter expression. For example:
Resolver API:
Book book = new Book();
book.setAuthor("Leo");
book.setCategory("Fiction");
book.setPrice(100.0d);
book.setTitle("JsonSurfer is great!");
System.out.print(compile("$.author").resolve(book, new PoJoResolver())); which prints "Leo". List<String> list = Arrays.asList("foo", "bar");
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("list", list);
System.out.println(compile("$.list[1]").resolve(map, JavaCollectionProvider.INSTANCE)); which prints "bar".
Binaray format (Jackson only)By importing Jackson binary format backend, JsonSurfer is capable to surfer with multiple binary object representation formats such as Avro, CBOR, Protobuf(A known bug to be fixed in Jackson 2.9.6), Smile and Ion. For example, if you want to surfer with CBOR data, firstly, CBOR format backend need to be imported as dependency.
Then create a JsonSurfer with CBOR-backed JacksonParser and surfer as usual surfer = new JsonSurfer(new JacksonParser(new CBORFactory()), provider); Find more examples here: https://github.com/jsurfer/JsonSurfer/blob/master/jsurfer-all/src/test/java/org/jsfr/json/JacksonParserTest.java Share data among processorsSince JsonSurfer emit data in the way of callback, it would be difficult if one of your processing depends one another. Therefore a simple transient map is added for sharing data among your processors. Following unit test shows how to use it: surfer.configBuilder().bind("$.store.book[1]", new JsonPathListener() {
@Override
public void onValue(Object value, ParsingContext context) {
context.save("foo", "bar");
}
}).bind("$.store.book[2]", new JsonPathListener() {
@Override
public void onValue(Object value, ParsingContext context) {
assertEquals("bar", context.load("foo", String.class));
}
}).bind("$.store.book[0]", new JsonPathListener() {
@Override
public void onValue(Object value, ParsingContext context) {
assertNull(context.load("foo", String.class));
}
}).buildAndSurf(read("sample.json")); Control parsing
SurfingConfiguration config = surfer.configBuilder()
.bind("$.store.book[0]", new JsonPathListener() {
@Override
public void onValue(Object value, ParsingContext context) {
LOGGER.info("The first pause");
context.pause();
}
})
.bind("$.store.book[1]", new JsonPathListener() {
@Override
public void onValue(Object value, ParsingContext context) {
LOGGER.info("The second pause");
context.pause();
}
}).build();
ResumableParser parser = surfer.getResumableParser(read("sample.json"), config);
assertFalse(parser.resume());
LOGGER.info("Start parsing");
parser.parse();
LOGGER.info("Resume from the first pause");
assertTrue(parser.resume());
LOGGER.info("Resume from the second pause");
assertTrue(parser.resume());
LOGGER.info("Parsing stopped");
assertFalse(parser.resume());
Java 8 Streams API supportAs of 1.4, JsonSurfer can create an iterator from Json and JsonPath. Matched value can be pulled from the iterator one by one without loading entire json into memory. Iterator iterator = surfer.iterator(read("sample.json"), JsonPathCompiler.compile("$.store.book[*]")); Java8 user can also convert the iterator into a Stream Stream<Object> targetStream = StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED),
false); Functions implmented by Streams API public static Stream<Object> toStream(String json, String path) {
Iterator<Object> iterator = JsonSurferJackson.INSTANCE.iterator(json, JsonPathCompiler.compile(path));
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
}
public static void main(String[] s) throws Exception {
String json = "[1,3,5,7,11]";
// Count
System.out.println(toStream(json, "$[*]").count());
// Max
toStream(json, "$[*]").mapToInt(o -> ((LongNode) o).asInt()).max().ifPresent(System.out::println);
// Min
toStream(json, "$[*]").mapToInt(o -> ((LongNode) o).asInt()).min().ifPresent(System.out::println);
// Average
toStream(json, "$[*]").mapToDouble(o -> ((LongNode) o).asDouble()).average().ifPresent(System.out::println);
} Non-Blocking parsingAs of 1.4, JsonSurfer support non-blocking parsing for JacksonParser. You can achieve 100% non-blocking JSON processing with JsonSurfer in a NIO application. Let's take a Vertx request handler as an example: Vertx vertx = Vertx.vertx();
HttpServer server = vertx.createHttpServer(new HttpServerOptions());
JsonSurfer surfer = JsonSurferJackson.INSTANCE;
SurfingConfiguration config = surfer.configBuilder()
.bind("$[*]", (JsonPathListener) (value, context) -> {
// Handle json
System.out.println(value);
}).build();
server.requestHandler(request -> {
NonBlockingParser parser = surfer.createNonBlockingParser(config);
request.handler(buffer -> {
byte[] bytes = buffer.getBytes();
System.out.println("Received " + bytes.length + " bytes");
parser.feed(bytes, 0, bytes.length);
});
request.endHandler(aVoid -> {
parser.endOfInput();
System.out.println("End of request");
request.response().end();
});
}).listen(8080); ExamplesSample Json: {
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论