1. Overview
1.概述
In this article, we will be looking at the Jackson Streaming API. It supports both reading and writing, and by using it, we can write high-performance and fast JSON parsers.
在这篇文章中,我们将研究Jackson Streaming API。它支持读和写,通过使用它,我们可以编写高性能和快速的JSON解析器。
On the flip-side, it is a bit difficult to use – every detail of JSON data needs to be handled explicitly in code.
反过来说,它有点难用–JSON数据的每个细节都需要在代码中明确处理。
2. Maven Dependency
2.Maven的依赖性
Firstly, we need to add a Maven dependency to the jackson-core:
首先,我们需要为jackson-core添加一个Maven依赖项。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.1</version>
</dependency>
3. Writing to JSON
3.写到JSON
We can write JSON content directly to the OutputStream by using a JsonGenerator class. Firstly, we need to create the instance of that object:
我们可以通过使用一个JsonGenerator类将JSON内容直接写入OutputStream。首先,我们需要创建该对象的实例。
ByteArrayOutputStream stream = new ByteArrayOutputStream();
JsonFactory jfactory = new JsonFactory();
JsonGenerator jGenerator = jfactory
.createGenerator(stream, JsonEncoding.UTF8);
Next, let’s say that we want to write a JSON with the following structure:
接下来,假设我们想写一个具有以下结构的JSON。
{
"name":"Tom",
"age":25,
"address":[
"Poland",
"5th avenue"
]
}
We can use an instance of the JsonGenerator to write specific fields directly to the OutputStream:
我们可以使用JsonGenerator的一个实例来直接向OutputStream:写入特定的字段。
jGenerator.writeStartObject();
jGenerator.writeStringField("name", "Tom");
jGenerator.writeNumberField("age", 25);
jGenerator.writeFieldName("address");
jGenerator.writeStartArray();
jGenerator.writeString("Poland");
jGenerator.writeString("5th avenue");
jGenerator.writeEndArray();
jGenerator.writeEndObject();
jGenerator.close();
To check if proper JSON was created, we can create a String object with JSON object in it:
为了检查是否创建了适当的JSON,我们可以创建一个包含JSON对象的String object。
String json = new String(stream.toByteArray(), "UTF-8");
assertEquals(
json,
"{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}");
4. Parsing JSON
4.解析JSON[/strong]
When we get a JSON String as an input, and we want to extract specific fields from it, a JsonParser class can be used:
当我们得到一个JSON String 作为输入,并且我们想从中提取特定的字段时,可以使用一个JsonParser类。
String json
= "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}";
JsonFactory jfactory = new JsonFactory();
JsonParser jParser = jfactory.createParser(json);
String parsedName = null;
Integer parsedAge = null;
List<String> addresses = new LinkedList<>();
We want to obtain parsedName, parsedAge, and addresses fields from input JSON. To achieve this, we need to handle low-level parsing logic and implement it ourselves:
我们想从输入的JSON中获得parsedName、parsedAge和地址字段。为了实现这一目标,我们需要处理低级别的解析逻辑,并自行实现。
while (jParser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jParser.getCurrentName();
if ("name".equals(fieldname)) {
jParser.nextToken();
parsedName = jParser.getText();
}
if ("age".equals(fieldname)) {
jParser.nextToken();
parsedAge = jParser.getIntValue();
}
if ("address".equals(fieldname)) {
jParser.nextToken();
while (jParser.nextToken() != JsonToken.END_ARRAY) {
addresses.add(jParser.getText());
}
}
}
jParser.close();
Depending on the field name, we are extracting it and assigning to a proper field. After parsing the document, all fields should have correct data:
根据字段名,我们将其提取并分配给一个适当的字段。在解析完文档后,所有字段都应该有正确的数据。
assertEquals(parsedName, "Tom");
assertEquals(parsedAge, (Integer) 25);
assertEquals(addresses, Arrays.asList("Poland", "5th avenue"));
5. Extracting JSON Parts
5.提取JSON部分
Sometimes, when we’re parsing a JSON document, we are interested in only one particular field.
有时,当我们解析一个JSON文档时,我们只对一个特定的字段感兴趣。
Ideally, in these situations, we want to only parse the beginning of the document, and once the needed field is found, we can abort processing.
理想情况下,在这些情况下,我们希望只解析文档的开头,一旦找到需要的字段,我们可以放弃处理。
Let’s say that we are interested only in the age field of the input JSON. In this case, we can implement parsing logic to stop parsing once needed field is found:
假设我们只对输入JSON的age字段感兴趣。在这种情况下,我们可以实现解析逻辑,一旦找到需要的字段就停止解析。
while (jParser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jParser.getCurrentName();
if ("age".equals(fieldname)) {
jParser.nextToken();
parsedAge = jParser.getIntValue();
return;
}
}
jParser.close();
After processing, the only parsedAge field will have a value:
处理后,唯一的parsedAge字段将有一个值。
assertNull(parsedName);
assertEquals(parsedAge, (Integer) 25);
assertTrue(addresses.isEmpty());
Thanks to that, parsing of the JSON document will be a lot faster because we do not need to read the whole document but only small part of it.
正因为如此,解析JSON文档的速度会快很多,因为我们不需要读取整个文档,只需要读取其中的一小部分。
6. Conclusion
6.结论
In this quick article, we’re looking at how we can leverage the Stream Processing API out of Jackson.
在这篇快速的文章中,我们要看一下我们如何利用Jackson的流处理API出来。
The implementation of all these examples and code snippets can be found over on GitHub – this is a Maven project, so it should be easy to import and run as it is.
所有这些例子和代码片段的实现都可以在GitHub上找到over–这是一个Maven项目,所以应该很容易导入并按原样运行。