JsonReader.
Next, create handler methods for each structure in your JSON text. You'll need a method for each object type and for each array type.
beginArray to consume
the array's opening bracket. Then create a while loop that accumulates values, terminating
when hasNext is false. Finally, read the array's closing bracket by calling endArray.
beginObject to consume
the object's opening brace. Then create a while loop that assigns values to local variables
based on their name. This loop should terminate when hasNext is false. Finally,
read the object's closing brace by calling endObject.
When a nested object or array is encountered, delegate to the corresponding handler method.
When an unknown name is encountered, strict parsers should fail with an exception. Lenient
parsers should call skipValue() to recursively skip the value's nested tokens, which may
otherwise conflict.
If a value may be null, you should first check using peek(). Null literals can be
consumed using either nextNull() or skipValue().
setStrictness(Strictness), the default is Strictness#LEGACY_STRICT
setNestingLimit(int), the default is 255
JsonReader instances used internally by the com.google.gson.Gson class differs, and can be adjusted with the various com.google.gson.GsonBuilder methods.
[
{
"id": 912345678901,
"text": "How do I read a JSON stream in Java?",
"geo": null,
"user": {
"name": "json_newb",
"followers_count": 41
}
},
{
"id": 912345678902,
"text": "@json_newb just use JsonReader!",
"geo": [50.454722, -104.606667],
"user": {
"name": "jesse",
"followers_count": 2
}
}
]
This code implements the parser for the above structure:
public List<Message> readJsonStream(InputStream in) throws IOException {
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
try {
return readMessagesArray(reader);
} finally {
reader.close();
}
}
public List<Message> readMessagesArray(JsonReader reader) throws IOException {
List<Message> messages = new ArrayList<>();
reader.beginArray();
while (reader.hasNext()) {
messages.add(readMessage(reader));
}
reader.endArray();
return messages;
}
public Message readMessage(JsonReader reader) throws IOException {
long id = -1;
String text = null;
User user = null;
List<Double> geo = null;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("id")) {
id = reader.nextLong();
} else if (name.equals("text")) {
text = reader.nextString();
} else if (name.equals("geo") && reader.peek() != JsonToken.NULL) {
geo = readDoublesArray(reader);
} else if (name.equals("user")) {
user = readUser(reader);
} else {
reader.skipValue();
}
}
reader.endObject();
return new Message(id, text, user, geo);
}
public List<Double> readDoublesArray(JsonReader reader) throws IOException {
List<Double> doubles = new ArrayList<>();
reader.beginArray();
while (reader.hasNext()) {
doubles.add(reader.nextDouble());
}
reader.endArray();
return doubles;
}
public User readUser(JsonReader reader) throws IOException {
String username = null;
int followersCount = -1;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("name")) {
username = reader.nextString();
} else if (name.equals("followers_count")) {
followersCount = reader.nextInt();
} else {
reader.skipValue();
}
}
reader.endObject();
return new User(username, followersCount);
}
[1, "1"] may be read using either nextInt or nextString. This behavior is intended to prevent lossy numeric conversions:
double is JavaScript's only numeric type and very large values like 9007199254740993
cannot be represented exactly on that platform. To minimize precision loss, extremely large
values should be written and read as strings in JSON.
<script> tag.
Prefixing JSON files with ")]}'\n" makes them non-executable by <script>
tags, disarming the attack. Since the prefix is malformed JSON, strict parsing fails when it is
encountered. This class permits the non-execute prefix when lenient parsing is enabled.
Each JsonReader may be used to read a single JSON stream. Instances of this class are
not thread safe.
| Modifier and Type | Field and Description |
|---|---|
| private final char[] | buffer
Use a manual buffer to easily read and unread upcoming characters, and also so we can create strings without an intermediate StringBuilder. |
| pack-priv static final int | |
| pack-priv static final int | |
| private final Reader | in
The input JSON. |
| private int | |
| private int | |
| private int | |
| private static final long | |
| private int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private int[] | |
| private String[] | |
| pack-priv int | |
| private static final int | |
| private static final int | |
| private static final int | PEEKED_BUFFERED
When this is returned, the string value is stored in peekedString. |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | PEEKED_LONG
When this is returned, the integer value is stored in peekedLong. |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private long | peekedLong
A peeked value that was composed entirely of digits with an optional leading dash. |
| private int | peekedNumberLength
The number of characters in a peeked number literal. |
| private String | peekedString
A peeked string that should be parsed on the next double, long or string. |
| private int | |
| private int[] | stack
The nesting stack. |
| private int | |
| private Strictness |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public void | beginArray()
Consumes the next token from the JSON stream and asserts that it is the beginning of a new array. |
| public void | beginObject()
Consumes the next token from the JSON stream and asserts that it is the beginning of a new object. |
| private void | |
| public void | |
| private void | |
| pack-priv int | |
| public void | endArray()
Consumes the next token from the JSON stream and asserts that it is the end of the current array. |
| public void | endObject()
Consumes the next token from the JSON stream and asserts that it is the end of the current object. |
| private boolean | |
| public final int | |
| private String | |
| public String | |
| public String | getPreviousPath()
Returns a JSONPath in dot-notation to the previous (or current) location in the JSON document. |
| public final Strictness | |
| public boolean | |
| public final boolean | |
| private boolean | |
| pack-priv String | |
| public boolean | |
| public double | |
| public int | |
| public long | |
| public String | |
| private int | nextNonWhitespace(boolean throwOnEof)
Returns the next character in the stream that is neither whitespace nor a part of a comment. |
| public void | |
| private String | nextQuotedValue(char
either ' or ". quote)Returns the string up to but not including |
| public String | |
| private String | |
| public JsonToken | |
| private int | |
| private int | |
| private void | |
| private char | readEscapeCharacter()
Unescapes the character identified by the character or characters that immediately follow a backslash. |
| public final void | setLenient(boolean
whether this reader should be lenient. If true, the strictness is set to lenient)Strictness#LENIENT. If false, the strictness is set to Strictness#LEGACY_STRICT.
Deprecated
Please use
setStrictness(Strictness) instead.
Sets the strictness of this reader. |
| public final void | |
| public final void | setStrictness(Strictness
the new strictness value of this reader. May not be strictness)null.Configures how liberal this parser is in what it accepts. |
| private void | |
| private boolean | |
| private void | |
| private void | |
| public void | |
| private MalformedJsonException | syntaxError(String message)
Throws a new |
| public String | |
| private IllegalStateException | |
| private void |
| buffer | back to summary |
|---|---|
| private final char[] buffer Use a manual buffer to easily read and unread upcoming characters, and also so we can create strings without an intermediate StringBuilder. We decode literals directly out of this buffer, so it must be at least as long as the longest token that can be reported as a number. | |
| BUFFER_SIZE | back to summary |
|---|---|
| pack-priv static final int BUFFER_SIZE | |
| DEFAULT_NESTING_LIMIT | back to summary |
|---|---|
| pack-priv static final int DEFAULT_NESTING_LIMIT | |
| in | back to summary |
|---|---|
| private final Reader in The input JSON. | |
| limit | back to summary |
|---|---|
| private int limit | |
| lineNumber | back to summary |
|---|---|
| private int lineNumber | |
| lineStart | back to summary |
|---|---|
| private int lineStart | |
| MIN_INCOMPLETE_INTEGER | back to summary |
|---|---|
| private static final long MIN_INCOMPLETE_INTEGER | |
| nestingLimit | back to summary |
|---|---|
| private int nestingLimit | |
| NUMBER_CHAR_DECIMAL | back to summary |
|---|---|
| private static final int NUMBER_CHAR_DECIMAL | |
| NUMBER_CHAR_DIGIT | back to summary |
|---|---|
| private static final int NUMBER_CHAR_DIGIT | |
| NUMBER_CHAR_EXP_DIGIT | back to summary |
|---|---|
| private static final int NUMBER_CHAR_EXP_DIGIT | |
| NUMBER_CHAR_EXP_E | back to summary |
|---|---|
| private static final int NUMBER_CHAR_EXP_E | |
| NUMBER_CHAR_EXP_SIGN | back to summary |
|---|---|
| private static final int NUMBER_CHAR_EXP_SIGN | |
| NUMBER_CHAR_FRACTION_DIGIT | back to summary |
|---|---|
| private static final int NUMBER_CHAR_FRACTION_DIGIT | |
| NUMBER_CHAR_NONE | back to summary |
|---|---|
| private static final int NUMBER_CHAR_NONE | |
| NUMBER_CHAR_SIGN | back to summary |
|---|---|
| private static final int NUMBER_CHAR_SIGN | |
| pathIndices | back to summary |
|---|---|
| private int[] pathIndices | |
| pathNames | back to summary |
|---|---|
| private String[] pathNames | |
| peeked | back to summary |
|---|---|
| pack-priv int peeked | |
| PEEKED_BEGIN_ARRAY | back to summary |
|---|---|
| private static final int PEEKED_BEGIN_ARRAY | |
| PEEKED_BEGIN_OBJECT | back to summary |
|---|---|
| private static final int PEEKED_BEGIN_OBJECT | |
| PEEKED_BUFFERED | back to summary |
|---|---|
| private static final int PEEKED_BUFFERED When this is returned, the string value is stored in peekedString. | |
| PEEKED_DOUBLE_QUOTED | back to summary |
|---|---|
| private static final int PEEKED_DOUBLE_QUOTED | |
| PEEKED_DOUBLE_QUOTED_NAME | back to summary |
|---|---|
| private static final int PEEKED_DOUBLE_QUOTED_NAME | |
| PEEKED_END_ARRAY | back to summary |
|---|---|
| private static final int PEEKED_END_ARRAY | |
| PEEKED_END_OBJECT | back to summary |
|---|---|
| private static final int PEEKED_END_OBJECT | |
| PEEKED_EOF | back to summary |
|---|---|
| private static final int PEEKED_EOF | |
| PEEKED_FALSE | back to summary |
|---|---|
| private static final int PEEKED_FALSE | |
| PEEKED_LONG | back to summary |
|---|---|
| private static final int PEEKED_LONG When this is returned, the integer value is stored in peekedLong. | |
| PEEKED_NONE | back to summary |
|---|---|
| private static final int PEEKED_NONE | |
| PEEKED_NULL | back to summary |
|---|---|
| private static final int PEEKED_NULL | |
| PEEKED_NUMBER | back to summary |
|---|---|
| private static final int PEEKED_NUMBER | |
| PEEKED_SINGLE_QUOTED | back to summary |
|---|---|
| private static final int PEEKED_SINGLE_QUOTED | |
| PEEKED_SINGLE_QUOTED_NAME | back to summary |
|---|---|
| private static final int PEEKED_SINGLE_QUOTED_NAME | |
| PEEKED_TRUE | back to summary |
|---|---|
| private static final int PEEKED_TRUE | |
| PEEKED_UNQUOTED | back to summary |
|---|---|
| private static final int PEEKED_UNQUOTED | |
| PEEKED_UNQUOTED_NAME | back to summary |
|---|---|
| private static final int PEEKED_UNQUOTED_NAME | |
| peekedLong | back to summary |
|---|---|
| private long peekedLong A peeked value that was composed entirely of digits with an optional leading dash. Positive values may not have a leading 0. | |
| peekedNumberLength | back to summary |
|---|---|
| private int peekedNumberLength The number of characters in a peeked number literal. Increment 'pos' by this after reading a number. | |
| peekedString | back to summary |
|---|---|
| private String peekedString A peeked string that should be parsed on the next double, long or string. This is populated before a numeric value is parsed and used if that parsing fails. | |
| pos | back to summary |
|---|---|
| private int pos | |
| stack | back to summary |
|---|---|
| private int[] stack The nesting stack. Using a manual array rather than an ArrayList saves 20%. | |
| stackSize | back to summary |
|---|---|
| private int stackSize | |
| strictness | back to summary |
|---|---|
| private Strictness strictness | |
| JsonReader | back to summary |
|---|---|
| public JsonReader(Reader in) Creates a new instance that reads a JSON-encoded stream from | |
| beginArray | back to summary |
|---|---|
| public void beginArray() throws IOException Consumes the next token from the JSON stream and asserts that it is the beginning of a new array.
| |
| beginObject | back to summary |
|---|---|
| public void beginObject() throws IOException Consumes the next token from the JSON stream and asserts that it is the beginning of a new object.
| |
| checkLenient | back to summary |
|---|---|
| private void checkLenient() throws MalformedJsonException | |
| close | back to summary |
|---|---|
| public void close() throws IOException Implements java. Closes this JSON reader and the underlying Using the JSON reader after it has been closed will throw an
| |
| consumeNonExecutePrefix | back to summary |
|---|---|
| private void consumeNonExecutePrefix() throws IOException Consumes the non-execute prefix if it exists. | |
| doPeek | back to summary |
|---|---|
pack-priv int doPeek() throws IOException
| |
| endArray | back to summary |
|---|---|
| public void endArray() throws IOException Consumes the next token from the JSON stream and asserts that it is the end of the current array.
| |
| endObject | back to summary |
|---|---|
| public void endObject() throws IOException Consumes the next token from the JSON stream and asserts that it is the end of the current object.
| |
| fillBuffer | back to summary |
|---|---|
| private boolean fillBuffer(int minimum) throws IOException Returns true once | |
| getNestingLimit | back to summary |
|---|---|
| public final int getNestingLimit() Returns the nesting limit of this reader.
| |
| getPath | back to summary |
|---|---|
| private String getPath(boolean usePreviousPath) | |
| getPath | back to summary |
|---|---|
| public String getPath() Returns a JSONPath in dot-notation to the next (or current) location in the JSON document. That means:
This method can be useful to add additional context to exception messages before a value is consumed, for example when the peeked token is unexpected. | |
| getPreviousPath | back to summary |
|---|---|
| public String getPreviousPath() Returns a JSONPath in dot-notation to the previous (or current) location in the JSON document. That means:
This method can be useful to add additional context to exception messages after a value has been consumed. | |
| getStrictness | back to summary |
|---|---|
| public final Strictness getStrictness() Returns the strictness of this reader.
| |
| hasNext | back to summary |
|---|---|
| public boolean hasNext() throws IOException Returns true if the current array or object has another element. | |
| isLenient | back to summary |
|---|---|
| public final boolean isLenient() Returns true if the
| |
| isLiteral | back to summary |
|---|---|
private boolean isLiteral(char c) throws IOException
| |
| locationString | back to summary |
|---|---|
| pack-priv String locationString() | |
| nextBoolean | back to summary |
|---|---|
| public boolean nextBoolean() throws IOException Returns the
| |
| nextDouble | back to summary |
|---|---|
| public double nextDouble() throws IOException Returns the
| |
| nextInt | back to summary |
|---|---|
| public int nextInt() throws IOException Returns the
| |
| nextLong | back to summary |
|---|---|
| public long nextLong() throws IOException Returns the
| |
| nextName | back to summary |
|---|---|
| public String nextName() throws IOException Returns the next token, a
| |
| nextNonWhitespace | back to summary |
|---|---|
| private int nextNonWhitespace(boolean throwOnEof) throws IOException Returns the next character in the stream that is neither whitespace nor a part of a comment.
When this returns, the returned character is always at | |
| nextNull | back to summary |
|---|---|
| public void nextNull() throws IOException Consumes the next token from the JSON stream and asserts that it is a literal null.
| |
| nextQuotedValue | back to summary |
|---|---|
| private String nextQuotedValue(char quote) throws IOException Returns the string up to but not including
| |
| nextString | back to summary |
|---|---|
| public String nextString() throws IOException Returns the
| |
| nextUnquotedValue | back to summary |
|---|---|
| private String nextUnquotedValue() throws IOException Returns an unquoted value as a string.
| |
| peek | back to summary |
|---|---|
| public JsonToken peek() throws IOException Returns the type of the next token without consuming it. | |
| peekKeyword | back to summary |
|---|---|
| private int peekKeyword() throws IOException | |
| peekNumber | back to summary |
|---|---|
| private int peekNumber() throws IOException | |
| push | back to summary |
|---|---|
| private void push(int newTop) throws MalformedJsonException | |
| readEscapeCharacter | back to summary |
|---|---|
| private char readEscapeCharacter() throws IOException Unescapes the character identified by the character or characters that immediately follow a backslash. The backslash '\' should have already been read. This supports both Unicode escapes "u000A" and two-character escapes "\n".
| |
| setLenient | back to summary |
|---|---|
| public final void setLenient(boolean lenient)
Deprecated Please use Sets the strictness of this reader.
| |
| setNestingLimit | back to summary |
|---|---|
| public final void setNestingLimit(int limit) Sets the nesting limit of this reader. The nesting limit defines how many JSON arrays or objects may be open at the same time. For
example a nesting limit of 0 means no arrays or objects may be opened at all, a nesting limit
of 1 means one array or object may be open at the same time, and so on. So a nesting limit of 3
allows reading the JSON data The nesting limit can help to protect against a The default nesting limit is 255.
| |
| setStrictness | back to summary |
|---|---|
| public final void setStrictness(Strictness strictness) Configures how liberal this parser is in what it accepts. In strict mode, the parser only accepts JSON in accordance with RFC 8259. In legacy strict mode (the default), only JSON in accordance with the RFC 8259 is accepted, with a few exceptions denoted below for backwards compatibility reasons. In lenient mode, all sort of non-spec compliant JSON is accepted (see below).
| |
| skipQuotedValue | back to summary |
|---|---|
| private void skipQuotedValue(char quote) throws IOException | |
| skipTo | back to summary |
|---|---|
private boolean skipTo(String toFind) throws IOException
| |
| skipToEndOfLine | back to summary |
|---|---|
| private void skipToEndOfLine() throws IOException Advances the position until after the next newline character. If the line is terminated by "\r\n", the '\n' must be consumed as whitespace by the caller. | |
| skipUnquotedValue | back to summary |
|---|---|
private void skipUnquotedValue() throws IOException
| |
| skipValue | back to summary |
|---|---|
| public void skipValue() throws IOException Skips the next value recursively. This method is intended for use when the JSON token stream contains unrecognized or unhandled values. The behavior depends on the type of the next JSON token:
| |
| syntaxError | back to summary |
|---|---|
| private MalformedJsonException syntaxError(String message) throws MalformedJsonException Throws a new | |
| toString | back to summary |
|---|---|
| public String toString() Overrides java. Doc from java. Returns a string representation of the object.
Satisfying this method's contract implies a non-
| |
| unexpectedTokenError | back to summary |
|---|---|
| private IllegalStateException unexpectedTokenError(String expected) throws IOException | |
| validateAscii | back to summary |
|---|---|
| private void validateAscii(String s) throws MalformedJsonException | |