🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# Gson - `JsonReader` > 原文: [https://howtodoinjava.com/gson/jsonreader-streaming-json-parser/](https://howtodoinjava.com/gson/jsonreader-streaming-json-parser/) 了解如何使用 Gson `JsonReader`类,该类是基于请求的流式 JSON 解析器。 它有助于将 JSON 作为令牌流读取。 ## 1\. `JsonReader` * `JsonReader`是流 JSON 解析器,并且是**拉式解析器**的示例。 推送解析器解析 JSON 令牌并将其推送到事件处理器中。 * 它有助于读取 JSON([RFC 7159](https://www.ietf.org/rfc/rfc7159.txt))编码的值作为令牌流。 * 它读取字面值(字符串,数字,布尔值和`null`)以及对象和数组的开始和结束定界符。 * 令牌以**深度优先顺序**遍历,与 JSON 文档中出现的顺序相同。 > 阅读更多: [XML](https://howtodoinjava.com/xml/sax-parser-read-xml-example/) 的流解析器 ## 2.令牌 在流模式下,每个 JSON 数据都被视为一个单独的令牌。 当我们使用`JsonReader`处理它时,每个令牌将被顺序处理。 例如, ```java { "name":"Lokesh" } ``` 在使用`JsonReader`进行解析时,上述 JSON 将生成 4 个令牌: * 令牌 1 = `{` * 令牌 2 = `name` * 令牌 3 = `Lokesh` * 令牌 4 = `}` ## 3.如何创建 GSON `JsonReader` 我们可以使用它的简单构造器创建一个`JsonReader`实例,该实例接受[`java.io.Reader`](https://docs.oracle.com/javase/10/docs/api/java/io/Reader.html)类型的输入流。 ```java String json = "{}"; JsonReader jsonReader = new JsonReader( new StringReader(json) ); ``` 我们可以根据 JSON 流的来源使用以下阅读器之一: * `BufferedReader` * `LineNumberReader` * `CharArrayReader` * `InputStreamReader` * `FileReader` * `FilterReader` * `PushbackReader` * `PipedReader` * `StringReader` ## 4.读取 JSON 流 在创建包装了有效 JSON 源的`JsonReader`之后,我们可以开始对流令牌进行迭代并查看令牌值。 以下是在令牌上使用`JsonReader`读取简单 JSON 的示例。 ```java import java.io.IOException; import java.io.StringReader; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; public class Main { public static void main(String[] args) throws Exception { String json = "{'id': 1001,'firstName': 'Lokesh','lastName': 'Gupta','email': null}"; JsonReader jsonReader = new JsonReader(new StringReader(json)); jsonReader.setLenient(true); try { while (jsonReader.hasNext()) { JsonToken nextToken = jsonReader.peek(); if (JsonToken.BEGIN_OBJECT.equals(nextToken)) { jsonReader.beginObject(); } else if (JsonToken.NAME.equals(nextToken)) { String name = jsonReader.nextName(); System.out.println("Token KEY >>>> " + name); } else if (JsonToken.STRING.equals(nextToken)) { String value = jsonReader.nextString(); System.out.println("Token Value >>>> " + value); } else if (JsonToken.NUMBER.equals(nextToken)) { long value = jsonReader.nextLong(); System.out.println("Token Value >>>> " + value); } else if (JsonToken.NULL.equals(nextToken)) { jsonReader.nextNull(); System.out.println("Token Value >>>> null"); } else if (JsonToken.END_OBJECT.equals(nextToken)) { jsonReader.endObject(); } } } catch (IOException e) { e.printStackTrace(); } finally { jsonReader.close(); } } } ``` ```java Token KEY >>>> id Token Value >>>> 1001 Token KEY >>>> firstName Token Value >>>> Lokesh Token KEY >>>> lastName Token Value >>>> Gupta Token KEY >>>> email Token Value >>>> null ``` 在上面的示例中: * `JsonReader`的`hasNext()`方法如果有更多令牌,则返回`true`。 * `peek()`方法返回下一个 JSON 令牌,但不移至下一个。 * 随后,多次调用`peek()`将返回相同的 JSON 令牌。 * 可以使用`JsonToken`类的常量检查返回令牌的类型。 * 使用`beginArray()`和`endArray()`方法检查数组的左括号`'['`和`']'`。 * 使用`beginObject()`和`endObject()`方法检查对象的左括号`'{'`和`'}'`。 令牌的密钥的类型为`JsonToken.NAME`。 使用`nextName()`方法获取密钥名称。 * 确定令牌类型后,使用`nextLong()`,`nextString()`和`nextInt()`等方法获取令牌的值。 * 可以使用`nextNull()`或`skipValue()`使用空字面值。 * 所有`next....()`方法都返回当前令牌的值,并将内部指针移到下一个。 * 当遇到未知名称时,严格的解析器应该失败,并带有异常。 宽松解析器应调用`skipValue()`来递归地跳过该值的嵌套令牌,否则可能会发生冲突。 将有关 Gson `JsonReader`的问题交给我。 学习愉快! 参考: [Gson 用户指南](https://github.com/google/gson) [`JsonReader` Java 文档](https://static.javadoc.io/com.google.code.gson/gson/2.8.5/com/google/gson/stream/JsonReader.html)