or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-api.mdcustomization.mdindex.mdnavigation.mdparsing.md

configuration.mddocs/

0

# Output Formatting and Configuration

1

2

JSON-Smart provides extensive configuration options through JSONStyle for controlling JSON output formatting, compression levels, and parser behavior. This document covers all configuration aspects for both serialization and parsing.

3

4

## JSONStyle - Output Formatting

5

6

JSONStyle controls how JSON is formatted during serialization, offering various compression levels and formatting options.

7

8

### Predefined Styles

9

10

```java { .api }

11

public static final JSONStyle NO_COMPRESS;

12

public static final JSONStyle MAX_COMPRESS;

13

public static final JSONStyle LT_COMPRESS;

14

```

15

16

Three predefined formatting styles for common use cases.

17

18

```java

19

JSONObject obj = new JSONObject()

20

.appendField("name", "John Doe")

21

.appendField("age", 30)

22

.appendField("active", true);

23

24

// No compression - readable formatting

25

String readable = obj.toJSONString(JSONStyle.NO_COMPRESS);

26

// {"name" : "John Doe", "age" : 30, "active" : true}

27

28

// Maximum compression - minimal size

29

String compressed = obj.toJSONString(JSONStyle.MAX_COMPRESS);

30

// {name:"John Doe",age:30,active:true}

31

32

// Light compression - balanced

33

String balanced = obj.toJSONString(JSONStyle.LT_COMPRESS);

34

// {"name":"John Doe","age":30,"active":true}

35

```

36

37

### Flag Constants

38

39

```java { .api }

40

public static final int FLAG_PROTECT_KEYS = 1;

41

public static final int FLAG_PROTECT_4WEB = 2;

42

public static final int FLAG_PROTECT_VALUES = 4;

43

public static final int FLAG_AGRESSIVE = 8;

44

public static final int FLAG_IGNORE_NULL = 16;

45

```

46

47

Individual flags that control specific formatting behaviors:

48

49

- **FLAG_PROTECT_KEYS**: Always quote object keys

50

- **FLAG_PROTECT_4WEB**: Use web-safe escaping

51

- **FLAG_PROTECT_VALUES**: Always quote string values

52

- **FLAG_AGRESSIVE**: Maximum compression (remove all unnecessary characters)

53

- **FLAG_IGNORE_NULL**: Skip null values in output

54

55

### Constructors

56

57

```java { .api }

58

public JSONStyle();

59

public JSONStyle(int FLAG);

60

```

61

62

Create custom formatting styles.

63

64

```java

65

// Default style

66

JSONStyle defaultStyle = new JSONStyle();

67

68

// Custom style with specific flags

69

JSONStyle customStyle = new JSONStyle(

70

JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_IGNORE_NULL

71

);

72

73

// Multiple flags combined

74

int webSafeFlags = JSONStyle.FLAG_PROTECT_KEYS |

75

JSONStyle.FLAG_PROTECT_4WEB |

76

JSONStyle.FLAG_IGNORE_NULL;

77

JSONStyle webSafe = new JSONStyle(webSafeFlags);

78

```

79

80

### Configuration Methods

81

82

```java { .api }

83

public boolean protectKeys();

84

public boolean protectValues();

85

public boolean protect4Web();

86

public boolean ignoreNull();

87

public boolean indent();

88

public boolean mustProtectKey(String s);

89

public boolean mustProtectValue(String s);

90

```

91

92

Query current configuration and test protection requirements.

93

94

```java

95

JSONStyle style = new JSONStyle(JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_IGNORE_NULL);

96

97

// Check configuration

98

boolean quotesKeys = style.protectKeys(); // true

99

boolean skipsNull = style.ignoreNull(); // true

100

boolean indented = style.indent(); // false

101

102

// Test specific values

103

boolean needsQuotes = style.mustProtectKey("validKey"); // true (always protect when flag set)

104

boolean valueNeedsQuotes = style.mustProtectValue("simple"); // depends on flag and content

105

```

106

107

## Output Formatting Examples

108

109

### Key Protection Examples

110

111

```java

112

JSONObject obj = new JSONObject()

113

.appendField("simpleKey", "value")

114

.appendField("key with spaces", "value")

115

.appendField("123numeric", "value")

116

.appendField("key-with-dashes", "value");

117

118

// Default style - quotes only when necessary

119

String normal = obj.toJSONString();

120

// {simpleKey:"value","key with spaces":"value","123numeric":"value","key-with-dashes":"value"}

121

122

// Always protect keys

123

JSONStyle protectKeys = new JSONStyle(JSONStyle.FLAG_PROTECT_KEYS);

124

String quoted = obj.toJSONString(protectKeys);

125

// {"simpleKey":"value","key with spaces":"value","123numeric":"value","key-with-dashes":"value"}

126

```

127

128

### Value Protection Examples

129

130

```java

131

JSONObject obj = new JSONObject()

132

.appendField("string", "simple")

133

.appendField("number", 42)

134

.appendField("boolean", true)

135

.appendField("special", "string with \"quotes\" and \n newlines");

136

137

// Default style

138

String normal = obj.toJSONString();

139

// {string:simple,number:42,boolean:true,special:"string with \"quotes\" and \n newlines"}

140

141

// Always protect string values

142

JSONStyle protectValues = new JSONStyle(JSONStyle.FLAG_PROTECT_VALUES);

143

String quoted = obj.toJSONString(protectValues);

144

// {string:"simple",number:42,boolean:true,special:"string with \"quotes\" and \n newlines"}

145

```

146

147

### Null Handling Examples

148

149

```java

150

JSONObject obj = new JSONObject()

151

.appendField("name", "John")

152

.appendField("middle", null)

153

.appendField("age", 30)

154

.appendField("email", null);

155

156

// Default style - includes nulls

157

String withNulls = obj.toJSONString();

158

// {name:"John",middle:null,age:30,email:null}

159

160

// Ignore null values

161

JSONStyle ignoreNull = new JSONStyle(JSONStyle.FLAG_IGNORE_NULL);

162

String noNulls = obj.toJSONString(ignoreNull);

163

// {name:"John",age:30}

164

```

165

166

### Web-Safe Formatting

167

168

```java

169

JSONObject obj = new JSONObject()

170

.appendField("html", "<script>alert('xss')</script>")

171

.appendField("path", "/api/users")

172

.appendField("callback", "jsonp_callback_123");

173

174

// Default style

175

String normal = obj.toJSONString();

176

// {html:"<script>alert('xss')</script>",path:"/api/users",callback:"jsonp_callback_123"}

177

178

// Web-safe escaping

179

JSONStyle webSafe = new JSONStyle(JSONStyle.FLAG_PROTECT_4WEB);

180

String safe = obj.toJSONString(webSafe);

181

// {html:"\\u003cscript\\u003ealert('xss')\\u003c\\/script\\u003e",path:"\\/api\\/users",callback:"jsonp_callback_123"}

182

```

183

184

## Output Writing Methods

185

186

JSONStyle provides methods for writing JSON output with specific formatting.

187

188

### String Writing

189

190

```java { .api }

191

public void writeString(Appendable out, String value) throws IOException;

192

public void escape(String s, Appendable out);

193

```

194

195

Write strings with appropriate escaping and quoting.

196

197

```java

198

JSONStyle style = new JSONStyle(JSONStyle.FLAG_PROTECT_VALUES);

199

StringBuilder sb = new StringBuilder();

200

201

// Write quoted string

202

style.writeString(sb, "Hello World");

203

System.out.println(sb.toString()); // "Hello World"

204

205

// Write with escaping

206

sb.setLength(0);

207

style.escape("Text with \"quotes\"", sb);

208

System.out.println(sb.toString()); // Text with \"quotes\"

209

```

210

211

### Structure Writing Methods

212

213

```java { .api }

214

public void objectStart(Appendable out) throws IOException;

215

public void objectStop(Appendable out) throws IOException;

216

public void objectFirstStart(Appendable out) throws IOException;

217

public void objectNext(Appendable out) throws IOException;

218

public void objectElmStop(Appendable out) throws IOException;

219

public void objectEndOfKey(Appendable out) throws IOException;

220

221

public void arrayStart(Appendable out) throws IOException;

222

public void arrayStop(Appendable out) throws IOException;

223

public void arrayfirstObject(Appendable out) throws IOException;

224

public void arrayNextElm(Appendable out) throws IOException;

225

public void arrayObjectEnd(Appendable out) throws IOException;

226

```

227

228

Low-level methods for manual JSON construction with consistent formatting.

229

230

```java

231

JSONStyle style = JSONStyle.NO_COMPRESS;

232

StringBuilder json = new StringBuilder();

233

234

// Manual object construction

235

style.objectStart(json); // {

236

style.objectFirstStart(json); //

237

json.append("\"name\"");

238

style.objectEndOfKey(json); // :

239

style.writeString(json, "John"); // "John"

240

style.objectNext(json); // ,

241

json.append("\"age\"");

242

style.objectEndOfKey(json); // :

243

json.append("30");

244

style.objectElmStop(json); //

245

style.objectStop(json); // }

246

247

System.out.println(json.toString()); // {"name" : "John", "age" : 30}

248

```

249

250

## Custom Style Creation

251

252

### Custom Compression Style

253

254

```java

255

// Create highly compressed style for APIs

256

public class APICompressionStyle extends JSONStyle {

257

258

public APICompressionStyle() {

259

super(FLAG_AGRESSIVE | FLAG_IGNORE_NULL | FLAG_PROTECT_4WEB);

260

}

261

262

@Override

263

public boolean mustProtectKey(String key) {

264

// Never protect keys that are simple identifiers

265

if (key.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {

266

return false;

267

}

268

return super.mustProtectKey(key);

269

}

270

271

@Override

272

public boolean mustProtectValue(String value) {

273

// Don't protect simple numeric strings

274

if (value.matches("^\\d+$")) {

275

return false;

276

}

277

return super.mustProtectValue(value);

278

}

279

}

280

281

// Usage

282

JSONStyle apiStyle = new APICompressionStyle();

283

JSONObject data = new JSONObject()

284

.appendField("userId", "12345")

285

.appendField("status", "active")

286

.appendField("count", null);

287

288

String compressed = data.toJSONString(apiStyle);

289

// {userId:12345,status:active} (null ignored, minimal quotes)

290

```

291

292

### Debug-Friendly Style

293

294

```java

295

public class DebugJSONStyle extends JSONStyle {

296

297

public DebugJSONStyle() {

298

super(FLAG_PROTECT_KEYS | FLAG_PROTECT_VALUES);

299

}

300

301

@Override

302

public void objectStart(Appendable out) throws IOException {

303

out.append("{\n ");

304

}

305

306

@Override

307

public void objectStop(Appendable out) throws IOException {

308

out.append("\n}");

309

}

310

311

@Override

312

public void objectNext(Appendable out) throws IOException {

313

out.append(",\n ");

314

}

315

316

@Override

317

public void objectEndOfKey(Appendable out) throws IOException {

318

out.append(" : ");

319

}

320

321

@Override

322

public void arrayStart(Appendable out) throws IOException {

323

out.append("[\n ");

324

}

325

326

@Override

327

public void arrayStop(Appendable out) throws IOException {

328

out.append("\n ]");

329

}

330

331

@Override

332

public void arrayNextElm(Appendable out) throws IOException {

333

out.append(",\n ");

334

}

335

}

336

337

// Usage

338

JSONStyle debugStyle = new DebugJSONStyle();

339

JSONObject obj = new JSONObject()

340

.appendField("name", "John")

341

.appendField("items", Arrays.asList("a", "b", "c"));

342

343

String formatted = obj.toJSONString(debugStyle);

344

/*

345

{

346

"name" : "John",

347

"items" : [

348

"a",

349

"b",

350

"c"

351

]

352

}

353

*/

354

```

355

356

## Parser Configuration

357

358

While JSONStyle controls output formatting, parser configuration is handled through JSONParser mode flags.

359

360

### Common Parser Configurations

361

362

```java

363

// Strict web API parsing

364

int webApiMode = JSONParser.MODE_RFC4627 | JSONParser.REJECT_127_CHAR;

365

JSONParser webParser = new JSONParser(webApiMode);

366

367

// Lenient file parsing

368

int fileMode = JSONParser.MODE_PERMISSIVE |

369

JSONParser.ACCEPT_SIMPLE_QUOTE |

370

JSONParser.ACCEPT_USELESS_COMMA;

371

JSONParser fileParser = new JSONParser(fileMode);

372

373

// High-precision financial parsing

374

int financialMode = JSONParser.MODE_PERMISSIVE |

375

JSONParser.USE_HI_PRECISION_FLOAT |

376

JSONParser.BIG_DIGIT_UNRESTRICTED;

377

JSONParser financialParser = new JSONParser(financialMode);

378

```

379

380

### Configuration Validation

381

382

```java

383

public class ConfigurationValidator {

384

385

public static void validateStyleConfiguration(JSONStyle style) {

386

System.out.println("Style Configuration:");

387

System.out.println(" Protect Keys: " + style.protectKeys());

388

System.out.println(" Protect Values: " + style.protectValues());

389

System.out.println(" Web Safe: " + style.protect4Web());

390

System.out.println(" Ignore Null: " + style.ignoreNull());

391

System.out.println(" Indent: " + style.indent());

392

}

393

394

public static void testStyleOutput(JSONStyle style) {

395

JSONObject testObj = new JSONObject()

396

.appendField("simpleKey", "simpleValue")

397

.appendField("key with spaces", "value with \"quotes\"")

398

.appendField("nullValue", null)

399

.appendField("number", 42)

400

.appendField("htmlContent", "<script>alert('test')</script>");

401

402

String output = testObj.toJSONString(style);

403

System.out.println("Output: " + output);

404

System.out.println("Length: " + output.length());

405

}

406

}

407

408

// Usage

409

JSONStyle customStyle = new JSONStyle(

410

JSONStyle.FLAG_PROTECT_KEYS |

411

JSONStyle.FLAG_IGNORE_NULL |

412

JSONStyle.FLAG_PROTECT_4WEB

413

);

414

415

ConfigurationValidator.validateStyleConfiguration(customStyle);

416

ConfigurationValidator.testStyleOutput(customStyle);

417

```

418

419

## Performance Considerations

420

421

### Style Selection for Performance

422

423

```java

424

// Fastest serialization - minimal processing

425

JSONStyle fastest = JSONStyle.MAX_COMPRESS;

426

427

// Memory efficient - excludes nulls

428

JSONStyle memoryEfficient = new JSONStyle(JSONStyle.FLAG_IGNORE_NULL);

429

430

// Network efficient - maximum compression + null exclusion

431

JSONStyle networkEfficient = new JSONStyle(

432

JSONStyle.FLAG_AGRESSIVE | JSONStyle.FLAG_IGNORE_NULL

433

);

434

435

// Benchmark different styles

436

public void benchmarkStyles(Object testData, int iterations) {

437

JSONStyle[] styles = {

438

JSONStyle.NO_COMPRESS,

439

JSONStyle.LT_COMPRESS,

440

JSONStyle.MAX_COMPRESS,

441

networkEfficient

442

};

443

444

for (JSONStyle style : styles) {

445

long start = System.nanoTime();

446

for (int i = 0; i < iterations; i++) {

447

String json = JSONValue.toJSONString(testData, style);

448

}

449

long end = System.nanoTime();

450

451

String sample = JSONValue.toJSONString(testData, style);

452

System.out.printf("Style: %s, Time: %dms, Size: %d bytes%n",

453

style.getClass().getSimpleName(),

454

(end - start) / 1_000_000,

455

sample.length());

456

}

457

}

458

```

459

460

### Configuration Caching

461

462

```java

463

public class StyleCache {

464

private static final Map<String, JSONStyle> STYLE_CACHE = new ConcurrentHashMap<>();

465

466

public static JSONStyle getOrCreateStyle(String name, int flags) {

467

return STYLE_CACHE.computeIfAbsent(name, k -> new JSONStyle(flags));

468

}

469

470

// Predefined cached styles

471

public static final JSONStyle WEB_API_STYLE = getOrCreateStyle("webApi",

472

JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_PROTECT_4WEB | JSONStyle.FLAG_IGNORE_NULL);

473

474

public static final JSONStyle MOBILE_API_STYLE = getOrCreateStyle("mobileApi",

475

JSONStyle.FLAG_AGRESSIVE | JSONStyle.FLAG_IGNORE_NULL);

476

477

public static final JSONStyle DEBUG_STYLE = getOrCreateStyle("debug",

478

JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_PROTECT_VALUES);

479

}

480

481

// Usage

482

String webJson = JSONValue.toJSONString(data, StyleCache.WEB_API_STYLE);

483

String mobileJson = JSONValue.toJSONString(data, StyleCache.MOBILE_API_STYLE);

484

```

485

486

## Complete Configuration Examples

487

488

### REST API Configuration

489

490

```java

491

public class RestApiConfig {

492

// Input parsing - strict but allow common relaxations

493

private static final int API_PARSER_MODE =

494

JSONParser.MODE_RFC4627 |

495

JSONParser.ACCEPT_TAILLING_SPACE |

496

JSONParser.USE_INTEGER_STORAGE;

497

498

// Output formatting - web-safe and compact

499

private static final JSONStyle API_OUTPUT_STYLE = new JSONStyle(

500

JSONStyle.FLAG_PROTECT_KEYS |

501

JSONStyle.FLAG_PROTECT_4WEB |

502

JSONStyle.FLAG_IGNORE_NULL

503

);

504

505

public static final JSONParser API_PARSER = new JSONParser(API_PARSER_MODE);

506

507

public static <T> T parseRequest(String json, Class<T> type) throws ParseException {

508

return API_PARSER.parse(json, type);

509

}

510

511

public static String formatResponse(Object data) {

512

return JSONValue.toJSONString(data, API_OUTPUT_STYLE);

513

}

514

}

515

516

// Usage

517

try {

518

MyRequest request = RestApiConfig.parseRequest(requestJson, MyRequest.class);

519

MyResponse response = processRequest(request);

520

String responseJson = RestApiConfig.formatResponse(response);

521

return responseJson;

522

} catch (ParseException e) {

523

String errorJson = RestApiConfig.formatResponse(

524

Map.of("error", "Invalid JSON", "details", e.getMessage())

525

);

526

return errorJson;

527

}

528

```

529

530

### File Processing Configuration

531

532

```java

533

public class FileProcessingConfig {

534

// Lenient parsing for user-generated files

535

private static final int FILE_PARSER_MODE =

536

JSONParser.MODE_PERMISSIVE |

537

JSONParser.ACCEPT_SIMPLE_QUOTE |

538

JSONParser.ACCEPT_USELESS_COMMA |

539

JSONParser.ACCEPT_LEADING_ZERO |

540

JSONParser.IGNORE_CONTROL_CHAR;

541

542

// Readable output for file generation

543

private static final JSONStyle FILE_OUTPUT_STYLE = JSONStyle.NO_COMPRESS;

544

545

public static final JSONParser FILE_PARSER = new JSONParser(FILE_PARSER_MODE);

546

547

public static Object parseFile(Path filePath) throws IOException, ParseException {

548

try (Reader reader = Files.newBufferedReader(filePath)) {

549

return FILE_PARSER.parse(reader);

550

}

551

}

552

553

public static void writeFile(Object data, Path filePath) throws IOException {

554

try (Writer writer = Files.newBufferedWriter(filePath)) {

555

JSONValue.writeJSONString(data, writer, FILE_OUTPUT_STYLE);

556

}

557

}

558

}

559

```

560

561

### Configuration Testing Utility

562

563

```java

564

public class ConfigurationTester {

565

566

public static void testConfiguration(String name, JSONParser parser, JSONStyle style) {

567

System.out.println("Testing configuration: " + name);

568

569

// Test various JSON inputs

570

String[] testInputs = {

571

"{\"valid\": \"json\"}",

572

"{'single': 'quotes'}",

573

"{\"trailing\": \"comma\",}",

574

"{\"leading\": 007}",

575

"{\"unicode\": \"\\u0041\"}",

576

"{\"null\": null}",

577

"{\"number\": 123.456789012345678901234567890}"

578

};

579

580

for (String input : testInputs) {

581

try {

582

Object parsed = parser.parse(input);

583

String output = JSONValue.toJSONString(parsed, style);

584

System.out.printf(" ✓ %s -> %s%n", input, output);

585

} catch (ParseException e) {

586

System.out.printf(" ✗ %s -> ERROR: %s%n", input, e.getMessage());

587

}

588

}

589

590

System.out.println();

591

}

592

593

public static void main(String[] args) {

594

// Test different configurations

595

testConfiguration("Strict Web API",

596

new JSONParser(JSONParser.MODE_RFC4627),

597

new JSONStyle(JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_PROTECT_4WEB));

598

599

testConfiguration("Lenient File Processing",

600

new JSONParser(JSONParser.MODE_PERMISSIVE),

601

JSONStyle.NO_COMPRESS);

602

603

testConfiguration("High Performance API",

604

new JSONParser(JSONParser.MODE_PERMISSIVE),

605

JSONStyle.MAX_COMPRESS);

606

}

607

}

608

```