0
# Streaming API
1
2
Gson's streaming API provides memory-efficient processing of JSON data through JsonReader and JsonWriter classes. This is essential for handling large JSON documents without loading them entirely into memory.
3
4
## JsonReader
5
6
Read JSON content in a streaming fashion.
7
8
```java { .api }
9
public class JsonReader implements Closeable {
10
public JsonReader(Reader in);
11
12
// Configuration
13
public void setLenient(boolean lenient);
14
public boolean isLenient();
15
public void setStrictness(Strictness strictness);
16
public Strictness getStrictness();
17
18
// Navigation
19
public JsonToken peek() throws IOException;
20
public JsonToken nextToken() throws IOException;
21
public void skipValue() throws IOException;
22
23
// Object navigation
24
public void beginObject() throws IOException;
25
public void endObject() throws IOException;
26
public String nextName() throws IOException;
27
28
// Array navigation
29
public void beginArray() throws IOException;
30
public void endArray() throws IOException;
31
32
// Value reading
33
public String nextString() throws IOException;
34
public boolean nextBoolean() throws IOException;
35
public void nextNull() throws IOException;
36
public double nextDouble() throws IOException;
37
public long nextLong() throws IOException;
38
public int nextInt() throws IOException;
39
40
// State
41
public boolean hasNext() throws IOException;
42
public String getPath();
43
44
// Resource management
45
public void close() throws IOException;
46
}
47
```
48
49
### JsonToken Enum
50
51
```java { .api }
52
public enum JsonToken {
53
BEGIN_ARRAY,
54
END_ARRAY,
55
BEGIN_OBJECT,
56
END_OBJECT,
57
NAME,
58
STRING,
59
NUMBER,
60
BOOLEAN,
61
NULL,
62
END_DOCUMENT
63
}
64
```
65
66
**Reading JSON objects:**
67
```java
68
String json = "{\"name\":\"Alice\",\"age\":30,\"active\":true}";
69
JsonReader reader = new JsonReader(new StringReader(json));
70
71
reader.beginObject();
72
while (reader.hasNext()) {
73
String name = reader.nextName();
74
switch (name) {
75
case "name":
76
String personName = reader.nextString();
77
break;
78
case "age":
79
int age = reader.nextInt();
80
break;
81
case "active":
82
boolean active = reader.nextBoolean();
83
break;
84
default:
85
reader.skipValue(); // Skip unknown properties
86
break;
87
}
88
}
89
reader.endObject();
90
reader.close();
91
```
92
93
**Reading JSON arrays:**
94
```java
95
String json = "[1,2,3,4,5]";
96
JsonReader reader = new JsonReader(new StringReader(json));
97
98
reader.beginArray();
99
while (reader.hasNext()) {
100
int value = reader.nextInt();
101
System.out.println(value);
102
}
103
reader.endArray();
104
reader.close();
105
```
106
107
**Reading complex nested structures:**
108
```java
109
String json = "{\"users\":[{\"name\":\"Alice\",\"age\":30},{\"name\":\"Bob\",\"age\":25}]}";
110
JsonReader reader = new JsonReader(new StringReader(json));
111
112
reader.beginObject();
113
while (reader.hasNext()) {
114
String name = reader.nextName();
115
if ("users".equals(name)) {
116
reader.beginArray();
117
while (reader.hasNext()) {
118
reader.beginObject();
119
String userName = null;
120
int age = 0;
121
while (reader.hasNext()) {
122
String fieldName = reader.nextName();
123
if ("name".equals(fieldName)) {
124
userName = reader.nextString();
125
} else if ("age".equals(fieldName)) {
126
age = reader.nextInt();
127
} else {
128
reader.skipValue();
129
}
130
}
131
reader.endObject();
132
System.out.println("User: " + userName + ", Age: " + age);
133
}
134
reader.endArray();
135
} else {
136
reader.skipValue();
137
}
138
}
139
reader.endObject();
140
reader.close();
141
```
142
143
## JsonWriter
144
145
Write JSON content in a streaming fashion.
146
147
```java { .api }
148
public class JsonWriter implements Closeable, Flushable {
149
public JsonWriter(Writer out);
150
151
// Configuration
152
public void setLenient(boolean lenient);
153
public boolean isLenient();
154
public void setStrictness(Strictness strictness);
155
public Strictness getStrictness();
156
public void setIndent(String indent);
157
public void setHtmlSafe(boolean htmlSafe);
158
public boolean isHtmlSafe();
159
public void setSerializeNulls(boolean serializeNulls);
160
public boolean getSerializeNulls();
161
162
// Object writing
163
public JsonWriter beginObject() throws IOException;
164
public JsonWriter endObject() throws IOException;
165
public JsonWriter name(String name) throws IOException;
166
167
// Array writing
168
public JsonWriter beginArray() throws IOException;
169
public JsonWriter endArray() throws IOException;
170
171
// Value writing
172
public JsonWriter value(String value) throws IOException;
173
public JsonWriter nullValue() throws IOException;
174
public JsonWriter value(boolean value) throws IOException;
175
public JsonWriter value(Boolean value) throws IOException;
176
public JsonWriter value(double value) throws IOException;
177
public JsonWriter value(long value) throws IOException;
178
public JsonWriter value(Number value) throws IOException;
179
180
// JSON value writing
181
public JsonWriter jsonValue(String value) throws IOException;
182
183
// Resource management
184
public void flush() throws IOException;
185
public void close() throws IOException;
186
}
187
```
188
189
**Writing JSON objects:**
190
```java
191
StringWriter stringWriter = new StringWriter();
192
JsonWriter writer = new JsonWriter(stringWriter);
193
194
writer.beginObject();
195
writer.name("name").value("Alice");
196
writer.name("age").value(30);
197
writer.name("active").value(true);
198
writer.name("salary").nullValue();
199
writer.endObject();
200
201
writer.close();
202
String json = stringWriter.toString();
203
// Result: {"name":"Alice","age":30,"active":true,"salary":null}
204
```
205
206
**Writing JSON arrays:**
207
```java
208
StringWriter stringWriter = new StringWriter();
209
JsonWriter writer = new JsonWriter(stringWriter);
210
211
writer.beginArray();
212
writer.value(1);
213
writer.value(2);
214
writer.value(3);
215
writer.endArray();
216
217
writer.close();
218
String json = stringWriter.toString();
219
// Result: [1,2,3]
220
```
221
222
**Writing complex nested structures:**
223
```java
224
StringWriter stringWriter = new StringWriter();
225
JsonWriter writer = new JsonWriter(stringWriter);
226
227
writer.beginObject();
228
writer.name("users");
229
writer.beginArray();
230
231
writer.beginObject();
232
writer.name("name").value("Alice");
233
writer.name("age").value(30);
234
writer.name("hobbies");
235
writer.beginArray();
236
writer.value("reading");
237
writer.value("swimming");
238
writer.endArray();
239
writer.endObject();
240
241
writer.beginObject();
242
writer.name("name").value("Bob");
243
writer.name("age").value(25);
244
writer.name("hobbies");
245
writer.beginArray();
246
writer.value("gaming");
247
writer.endArray();
248
writer.endObject();
249
250
writer.endArray();
251
writer.endObject();
252
253
writer.close();
254
```
255
256
## Gson Integration
257
258
Create JsonReader and JsonWriter through Gson for consistent configuration:
259
260
```java { .api }
261
public JsonWriter newJsonWriter(Writer writer) throws IOException;
262
public JsonReader newJsonReader(Reader reader);
263
```
264
265
**Usage:**
266
```java
267
Gson gson = new GsonBuilder()
268
.setPrettyPrinting()
269
.setLenient()
270
.create();
271
272
// Create configured writer
273
StringWriter stringWriter = new StringWriter();
274
JsonWriter writer = gson.newJsonWriter(stringWriter);
275
276
// Create configured reader
277
JsonReader reader = gson.newJsonReader(new StringReader(json));
278
```
279
280
## Error Handling
281
282
```java { .api }
283
class MalformedJsonException extends IOException {
284
// Thrown when JSON structure is invalid
285
}
286
```
287
288
**Error handling example:**
289
```java
290
try {
291
JsonReader reader = new JsonReader(new StringReader(malformedJson));
292
reader.beginObject();
293
// ... reading logic
294
} catch (MalformedJsonException e) {
295
System.err.println("Malformed JSON: " + e.getMessage());
296
} catch (IOException e) {
297
System.err.println("I/O error: " + e.getMessage());
298
}
299
```
300
301
## Advanced Usage
302
303
### Lenient Mode
304
305
Allow relaxed JSON syntax:
306
```java
307
JsonReader reader = new JsonReader(new StringReader(json));
308
reader.setLenient(true);
309
310
// Now can read: {name: 'Alice', age: 30} (unquoted names, single quotes)
311
```
312
313
### Pretty Printing
314
315
Configure indentation for readable output:
316
```java
317
JsonWriter writer = new JsonWriter(new FileWriter("output.json"));
318
writer.setIndent(" "); // 2-space indentation
319
320
writer.beginObject();
321
writer.name("name").value("Alice");
322
writer.name("details");
323
writer.beginObject();
324
writer.name("age").value(30);
325
writer.endObject();
326
writer.endObject();
327
```
328
329
### Large File Processing
330
331
Process large JSON files efficiently:
332
```java
333
// Reading large file
334
try (FileReader fileReader = new FileReader("large-data.json");
335
JsonReader reader = new JsonReader(fileReader)) {
336
337
reader.beginArray();
338
while (reader.hasNext()) {
339
// Process each object without loading entire file
340
processObject(reader);
341
}
342
reader.endArray();
343
}
344
345
private void processObject(JsonReader reader) throws IOException {
346
reader.beginObject();
347
while (reader.hasNext()) {
348
String name = reader.nextName();
349
// Handle each field as needed
350
if ("data".equals(name)) {
351
// Process data field
352
} else {
353
reader.skipValue();
354
}
355
}
356
reader.endObject();
357
}
358
```
359
360
### Custom Adapter Integration
361
362
Use streaming API within custom TypeAdapters:
363
```java
364
public class PersonAdapter extends TypeAdapter<Person> {
365
@Override
366
public void write(JsonWriter out, Person person) throws IOException {
367
out.beginObject();
368
out.name("name").value(person.getName());
369
out.name("age").value(person.getAge());
370
out.endObject();
371
}
372
373
@Override
374
public Person read(JsonReader in) throws IOException {
375
Person person = new Person();
376
in.beginObject();
377
while (in.hasNext()) {
378
String name = in.nextName();
379
switch (name) {
380
case "name":
381
person.setName(in.nextString());
382
break;
383
case "age":
384
person.setAge(in.nextInt());
385
break;
386
default:
387
in.skipValue();
388
break;
389
}
390
}
391
in.endObject();
392
return person;
393
}
394
}
395
```