or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-processing.mdindex.mdstreaming-input.mdstreaming-output.mdtype-system.md

streaming-input.mddocs/

0

# Streaming JSON Input

1

2

Advanced JSON reading and deserialization using `JsonInput` for memory-efficient processing of large JSON documents. Provides fine-grained control over the parsing process, custom type coercers, and streaming access to JSON elements.

3

4

## Capabilities

5

6

### JsonInput Class

7

8

Streaming JSON input processor that implements `Closeable` for resource management.

9

10

```java { .api }

11

/**

12

* The JsonInput class defines the operations used to deserialize JSON strings into Java objects.

13

* Provides streaming access to JSON elements and supports custom type coercion.

14

*/

15

public class JsonInput implements Closeable {

16

17

// Configuration methods

18

19

/**

20

* Change how property setting is done. It's polite to set the value back once done processing.

21

*

22

* @param setter The new PropertySetting to use

23

* @return The previous PropertySetting that has just been replaced

24

*/

25

public PropertySetting propertySetting(PropertySetting setter);

26

27

/**

28

* Add the specified type coercers to the set installed in the JSON coercion manager.

29

*

30

* @param coercers array of zero or more TypeCoercer objects

31

* @return this JsonInput object with added type coercers

32

* @throws JsonException if this JsonInput has already begun processing its input

33

*/

34

public JsonInput addCoercers(TypeCoercer<?>... coercers);

35

36

/**

37

* Add the specified type coercers to the set installed in the JSON coercion manager.

38

*

39

* @param coercers iterable collection of TypeCoercer objects

40

* @return this JsonInput object with added type coercers

41

* @throws JsonException if this JsonInput has already begun processing its input

42

*/

43

public JsonInput addCoercers(Iterable<TypeCoercer<?>> coercers);

44

45

// Element inspection

46

47

/**

48

* Peek at the next input string character to determine the pending JSON element type.

49

*

50

* @return JsonType indicating the pending JSON element type

51

* @throws JsonException if unable to determine the type of the pending element

52

* @throws UncheckedIOException if an I/O exception is encountered

53

*/

54

public JsonType peek();

55

56

// Primitive value reading

57

58

/**

59

* Read the next element of the JSON input stream as a boolean value.

60

*

61

* @return true or false

62

* @throws JsonException if the next element isn't the expected boolean

63

* @throws UncheckedIOException if an I/O exception is encountered

64

*/

65

public boolean nextBoolean();

66

67

/**

68

* Read the next element of the JSON input stream as an object property name.

69

*

70

* @return JSON object property name

71

* @throws JsonException if the next element isn't a string followed by a colon

72

* @throws UncheckedIOException if an I/O exception is encountered

73

*/

74

public String nextName();

75

76

/**

77

* Read the next element of the JSON input stream as a null object.

78

*

79

* @return null object

80

* @throws JsonException if the next element isn't a null

81

* @throws UncheckedIOException if an I/O exception is encountered

82

*/

83

public Object nextNull();

84

85

/**

86

* Read the next element of the JSON input stream as a number.

87

*

88

* @return Number object

89

* @throws JsonException if the next element isn't a number

90

* @throws UncheckedIOException if an I/O exception is encountered

91

*/

92

public Number nextNumber();

93

94

/**

95

* Read the next element of the JSON input stream as a string.

96

*

97

* @return String object

98

* @throws JsonException if the next element isn't a string

99

* @throws UncheckedIOException if an I/O exception is encountered

100

*/

101

public String nextString();

102

103

/**

104

* Read the next element of the JSON input stream as an instant.

105

*

106

* @return Instant object

107

* @throws JsonException if the next element isn't a Long

108

* @throws UncheckedIOException if an I/O exception is encountered

109

*/

110

public Instant nextInstant();

111

112

// Container navigation

113

114

/**

115

* Determine whether an element is pending for the current container from the JSON input stream.

116

*

117

* @return true if an element is pending; otherwise false

118

* @throws JsonException if no container is open

119

* @throws UncheckedIOException if an I/O exception is encountered

120

*/

121

public boolean hasNext();

122

123

/**

124

* Process the opening square bracket of a JSON array.

125

*

126

* @throws UncheckedIOException if an I/O exception is encountered

127

*/

128

public void beginArray();

129

130

/**

131

* Process the closing square bracket of a JSON array.

132

*

133

* @throws UncheckedIOException if an I/O exception is encountered

134

*/

135

public void endArray();

136

137

/**

138

* Process the opening curly brace of a JSON object.

139

*

140

* @throws UncheckedIOException if an I/O exception is encountered

141

*/

142

public void beginObject();

143

144

/**

145

* Process the closing curly brace of a JSON object.

146

*

147

* @throws UncheckedIOException if an I/O exception is encountered

148

*/

149

public void endObject();

150

151

/**

152

* Discard the pending JSON property value.

153

*

154

* @throws JsonException if the pending element isn't a value type

155

* @throws UncheckedIOException if an I/O exception is encountered

156

*/

157

public void skipValue();

158

159

// High-level reading methods

160

161

/**

162

* Read the next element from the JSON input stream as the specified type.

163

*

164

* @param type data type for deserialization (class or TypeToken)

165

* @return object of the specified type deserialized from the JSON input stream

166

* Returns null if the input string is exhausted

167

* @param <T> result type (as specified by type)

168

* @throws JsonException if coercion of the next element to the specified type fails

169

* @throws UncheckedIOException if an I/O exception is encountered

170

*/

171

public <T> T read(Type type);

172

173

/**

174

* Read an array of elements from the JSON input stream with elements as the specified type.

175

*

176

* @param type data type for deserialization (class or TypeToken)

177

* @return list of objects of the specified type deserialized from the JSON input stream

178

* Returns null if the input string is exhausted

179

* @param <T> result type of the item in the list (as specified by type)

180

* @throws JsonException if coercion of the next element to the specified type fails

181

* @throws UncheckedIOException if an I/O exception is encountered

182

*/

183

public <T> List<T> readArray(Type type);

184

185

// Resource management

186

187

/**

188

* Close the input stream.

189

*

190

* @throws UncheckedIOException if an I/O exception is encountered

191

*/

192

public void close();

193

}

194

```

195

196

### JsonType Enum

197

198

Enumeration of JSON element types for parsing control.

199

200

```java { .api }

201

/**

202

* Used to specify the pending JSON element type.

203

*/

204

public enum JsonType {

205

/** Boolean value */

206

BOOLEAN,

207

/** property name */

208

NAME,

209

/** null value */

210

NULL,

211

/** numeric value */

212

NUMBER,

213

/** start of object */

214

START_MAP,

215

/** end of object */

216

END_MAP,

217

/** start of array */

218

START_COLLECTION,

219

/** end of array */

220

END_COLLECTION,

221

/** string value */

222

STRING,

223

/** end of input */

224

END

225

}

226

```

227

228

## Usage Examples

229

230

### Basic Streaming Reading

231

232

```java

233

import org.openqa.selenium.json.Json;

234

import org.openqa.selenium.json.JsonInput;

235

import org.openqa.selenium.json.JsonType;

236

import java.io.StringReader;

237

238

Json json = new Json();

239

String jsonData = "{\"name\":\"John\",\"age\":30,\"active\":true}";

240

241

try (JsonInput input = json.newInput(new StringReader(jsonData))) {

242

input.beginObject();

243

244

while (input.hasNext()) {

245

String propertyName = input.nextName();

246

247

switch (propertyName) {

248

case "name":

249

String name = input.nextString();

250

System.out.println("Name: " + name);

251

break;

252

case "age":

253

Number age = input.nextNumber();

254

System.out.println("Age: " + age);

255

break;

256

case "active":

257

boolean active = input.nextBoolean();

258

System.out.println("Active: " + active);

259

break;

260

default:

261

input.skipValue(); // Skip unknown properties

262

}

263

}

264

265

input.endObject();

266

}

267

```

268

269

### Array Processing

270

271

```java

272

String jsonArray = "[\"apple\",\"banana\",\"cherry\"]";

273

274

try (JsonInput input = json.newInput(new StringReader(jsonArray))) {

275

List<String> fruits = new ArrayList<>();

276

277

input.beginArray();

278

while (input.hasNext()) {

279

fruits.add(input.nextString());

280

}

281

input.endArray();

282

283

System.out.println("Fruits: " + fruits);

284

}

285

286

// Or use the convenient readArray method

287

try (JsonInput input = json.newInput(new StringReader(jsonArray))) {

288

List<String> fruits = input.readArray(String.class);

289

System.out.println("Fruits: " + fruits);

290

}

291

```

292

293

### Type Inspection with Peek

294

295

```java

296

String jsonData = "{\"count\":42,\"message\":\"hello\",\"valid\":true}";

297

298

try (JsonInput input = json.newInput(new StringReader(jsonData))) {

299

input.beginObject();

300

301

while (input.hasNext()) {

302

String propertyName = input.nextName();

303

JsonType valueType = input.peek();

304

305

switch (valueType) {

306

case NUMBER:

307

Number num = input.nextNumber();

308

System.out.println(propertyName + " (number): " + num);

309

break;

310

case STRING:

311

String str = input.nextString();

312

System.out.println(propertyName + " (string): " + str);

313

break;

314

case BOOLEAN:

315

boolean bool = input.nextBoolean();

316

System.out.println(propertyName + " (boolean): " + bool);

317

break;

318

case NULL:

319

input.nextNull();

320

System.out.println(propertyName + " (null)");

321

break;

322

default:

323

input.skipValue();

324

System.out.println(propertyName + " (skipped)");

325

}

326

}

327

328

input.endObject();

329

}

330

```

331

332

### Custom Type Coercers

333

334

```java

335

import org.openqa.selenium.json.TypeCoercer;

336

import org.openqa.selenium.json.PropertySetting;

337

import java.lang.reflect.Type;

338

import java.util.function.BiFunction;

339

340

// Custom coercer for LocalDate

341

public class LocalDateCoercer extends TypeCoercer<LocalDate> {

342

@Override

343

public boolean test(Class<?> aClass) {

344

return LocalDate.class.isAssignableFrom(aClass);

345

}

346

347

@Override

348

public BiFunction<JsonInput, PropertySetting, LocalDate> apply(Type type) {

349

return (jsonInput, propertySetting) -> {

350

String dateStr = jsonInput.nextString();

351

return LocalDate.parse(dateStr);

352

};

353

}

354

}

355

356

// Usage

357

String jsonData = "{\"date\":\"2023-12-25\"}";

358

359

try (JsonInput input = json.newInput(new StringReader(jsonData))) {

360

input.addCoercers(new LocalDateCoercer());

361

362

input.beginObject();

363

input.nextName(); // "date"

364

LocalDate date = input.read(LocalDate.class);

365

input.endObject();

366

367

System.out.println("Date: " + date);

368

}

369

```

370

371

### Property Setting Strategies

372

373

```java

374

// Switch between property setting strategies

375

try (JsonInput input = json.newInput(new StringReader(jsonData))) {

376

PropertySetting original = input.propertySetting(PropertySetting.BY_FIELD);

377

378

// Read objects using direct field access

379

MyObject obj = input.read(MyObject.class);

380

381

// Restore original setting

382

input.propertySetting(original);

383

}

384

```

385

386

### Nested Object Processing

387

388

```java

389

String nestedJson = """

390

{

391

"user": {

392

"name": "John",

393

"preferences": {

394

"theme": "dark",

395

"notifications": true

396

}

397

},

398

"lastLogin": "2023-12-25T10:30:00Z"

399

}

400

""";

401

402

try (JsonInput input = json.newInput(new StringReader(nestedJson))) {

403

input.beginObject();

404

405

while (input.hasNext()) {

406

String key = input.nextName();

407

408

if ("user".equals(key)) {

409

input.beginObject();

410

411

while (input.hasNext()) {

412

String userKey = input.nextName();

413

414

if ("name".equals(userKey)) {

415

String name = input.nextString();

416

System.out.println("User name: " + name);

417

} else if ("preferences".equals(userKey)) {

418

input.beginObject();

419

420

while (input.hasNext()) {

421

String prefKey = input.nextName();

422

423

if ("theme".equals(prefKey)) {

424

String theme = input.nextString();

425

System.out.println("Theme: " + theme);

426

} else if ("notifications".equals(prefKey)) {

427

boolean notifications = input.nextBoolean();

428

System.out.println("Notifications: " + notifications);

429

} else {

430

input.skipValue();

431

}

432

}

433

434

input.endObject();

435

} else {

436

input.skipValue();

437

}

438

}

439

440

input.endObject();

441

} else if ("lastLogin".equals(key)) {

442

Instant lastLogin = input.nextInstant();

443

System.out.println("Last login: " + lastLogin);

444

} else {

445

input.skipValue();

446

}

447

}

448

449

input.endObject();

450

}

451

```