0
# Serialization and Output
1
2
Convert JSON values to various string formats and write to streams with configurable formatting options, supporting compact JSON, pretty-printed JSON, and human-readable Hjson output.
3
4
## Capabilities
5
6
### String Serialization
7
8
Convert JSON values to string representations with different formatting options.
9
10
```java { .api }
11
/**
12
* Returns a JSON string representation of this value in compact format
13
* @return JSON string representation
14
*/
15
String toString();
16
17
/**
18
* Returns a string representation of this value in the specified format
19
* @param format the output format (PLAIN, FORMATTED, or HJSON)
20
* @return string representation in the specified format
21
*/
22
String toString(Stringify format);
23
24
/**
25
* Returns an Hjson string representation of this value with custom options
26
* @param options the Hjson formatting options
27
* @return Hjson string representation
28
*/
29
String toString(HjsonOptions options);
30
```
31
32
**Usage Examples:**
33
34
```java
35
import org.hjson.JsonObject;
36
import org.hjson.JsonArray;
37
import org.hjson.Stringify;
38
import org.hjson.HjsonOptions;
39
40
JsonObject person = new JsonObject()
41
.add("name", "John Doe")
42
.add("age", 30)
43
.add("active", true)
44
.add("skills", new JsonArray().add("Java").add("Python").add("JavaScript"));
45
46
// Compact JSON (default)
47
String compact = person.toString();
48
System.out.println(compact);
49
// Output: {"name":"John Doe","age":30,"active":true,"skills":["Java","Python","JavaScript"]}
50
51
// Pretty-printed JSON
52
String formatted = person.toString(Stringify.FORMATTED);
53
System.out.println(formatted);
54
// Output:
55
// {
56
// "name": "John Doe",
57
// "age": 30,
58
// "active": true,
59
// "skills": [
60
// "Java",
61
// "Python",
62
// "JavaScript"
63
// ]
64
// }
65
66
// Human-readable Hjson
67
String hjson = person.toString(Stringify.HJSON);
68
System.out.println(hjson);
69
// Output:
70
// {
71
// name: John Doe
72
// age: 30
73
// active: true
74
// skills: [
75
// Java
76
// Python
77
// JavaScript
78
// ]
79
// }
80
81
// Hjson with custom options
82
HjsonOptions options = new HjsonOptions();
83
String customHjson = person.toString(options);
84
System.out.println(customHjson);
85
```
86
87
### Stream Writing
88
89
Write JSON values directly to output streams for efficient processing of large data.
90
91
```java { .api }
92
/**
93
* Writes the JSON representation of this value to the given writer in compact format
94
* @param writer the writer to write this value to
95
* @throws IOException if an I/O error occurs in the writer
96
*/
97
void writeTo(Writer writer) throws IOException;
98
99
/**
100
* Writes the string representation of this value to the given writer in the specified format
101
* @param writer the writer to write this value to
102
* @param format the output format (PLAIN, FORMATTED, or HJSON)
103
* @throws IOException if an I/O error occurs in the writer
104
*/
105
void writeTo(Writer writer, Stringify format) throws IOException;
106
107
/**
108
* Writes the Hjson representation of this value to the given writer with custom options
109
* @param writer the writer to write this value to
110
* @param options the Hjson formatting options
111
* @throws IOException if an I/O error occurs in the writer
112
*/
113
void writeTo(Writer writer, HjsonOptions options) throws IOException;
114
```
115
116
**Usage Examples:**
117
118
```java
119
import org.hjson.JsonObject;
120
import org.hjson.JsonArray;
121
import org.hjson.Stringify;
122
import java.io.FileWriter;
123
import java.io.StringWriter;
124
import java.io.IOException;
125
126
JsonArray data = new JsonArray();
127
for (int i = 0; i < 1000; i++) {
128
JsonObject item = new JsonObject()
129
.add("id", i)
130
.add("name", "Item " + i)
131
.add("value", Math.random() * 100);
132
data.add(item);
133
}
134
135
// Write to file
136
try (FileWriter fileWriter = new FileWriter("output.json")) {
137
data.writeTo(fileWriter, Stringify.FORMATTED);
138
System.out.println("Data written to output.json");
139
} catch (IOException e) {
140
System.err.println("Failed to write file: " + e.getMessage());
141
}
142
143
// Write to string (for in-memory processing)
144
StringWriter stringWriter = new StringWriter();
145
try {
146
data.writeTo(stringWriter, Stringify.HJSON);
147
String result = stringWriter.toString();
148
System.out.println("Generated " + result.length() + " characters");
149
} catch (IOException e) {
150
System.err.println("Failed to write to string: " + e.getMessage());
151
}
152
153
// Write to different streams based on content type
154
JsonObject config = new JsonObject()
155
.add("environment", "production")
156
.add("debug", false);
157
158
// Compact JSON for APIs
159
StringWriter apiWriter = new StringWriter();
160
config.writeTo(apiWriter); // Default compact format
161
String apiResponse = apiWriter.toString();
162
163
// Human-readable Hjson for configuration files
164
try (FileWriter configWriter = new FileWriter("app.hjson")) {
165
config.writeTo(configWriter, Stringify.HJSON);
166
}
167
```
168
169
### Output Format Options
170
171
Control the formatting and appearance of serialized output.
172
173
```java { .api }
174
/**
175
* Enumeration of output formatting options
176
*/
177
enum Stringify {
178
/**
179
* Compact JSON format with no whitespace
180
* Minimal size, suitable for network transmission and storage
181
*/
182
PLAIN,
183
184
/**
185
* Pretty-printed JSON format with indentation and line breaks
186
* Human-readable, suitable for debugging and development
187
*/
188
FORMATTED,
189
190
/**
191
* Hjson format with human-friendly syntax
192
* Most readable, suitable for configuration files and documentation
193
*/
194
HJSON
195
}
196
```
197
198
**Format Comparison Examples:**
199
200
```java
201
import org.hjson.JsonObject;
202
import org.hjson.JsonArray;
203
import org.hjson.Stringify;
204
205
JsonObject sample = new JsonObject()
206
.add("config", new JsonObject()
207
.add("name", "My App")
208
.add("version", "1.0.0"))
209
.add("features", new JsonArray()
210
.add("authentication")
211
.add("logging")
212
.add("caching"));
213
214
// PLAIN format (compact)
215
String plain = sample.toString(Stringify.PLAIN);
216
// {"config":{"name":"My App","version":"1.0.0"},"features":["authentication","logging","caching"]}
217
218
// FORMATTED format (pretty JSON)
219
String formatted = sample.toString(Stringify.FORMATTED);
220
// {
221
// "config": {
222
// "name": "My App",
223
// "version": "1.0.0"
224
// },
225
// "features": [
226
// "authentication",
227
// "logging",
228
// "caching"
229
// ]
230
// }
231
232
// HJSON format (human-friendly)
233
String hjson = sample.toString(Stringify.HJSON);
234
// {
235
// config: {
236
// name: My App
237
// version: "1.0.0"
238
// }
239
// features: [
240
// authentication
241
// logging
242
// caching
243
// ]
244
// }
245
246
// Compare sizes
247
System.out.println("Plain: " + plain.length() + " chars");
248
System.out.println("Formatted: " + formatted.length() + " chars");
249
System.out.println("Hjson: " + hjson.length() + " chars");
250
```
251
252
### Custom Formatting with HjsonOptions
253
254
Fine-tune Hjson output with custom configuration options.
255
256
```java { .api }
257
/**
258
* Configuration class for Hjson formatting options
259
*/
260
class HjsonOptions {
261
/**
262
* Creates default Hjson formatting options
263
*/
264
HjsonOptions();
265
266
/**
267
* Gets the array of Domain Specific Format providers for output
268
* @return array of DSF providers (may be null)
269
*/
270
IHjsonDsfProvider[] getDsfProviders();
271
272
/**
273
* Sets the Domain Specific Format providers for specialized value formatting
274
* @param providers array of DSF providers
275
*/
276
void setDsfProviders(IHjsonDsfProvider[] providers);
277
}
278
```
279
280
**Usage Examples:**
281
282
```java
283
import org.hjson.JsonObject;
284
import org.hjson.JsonValue;
285
import org.hjson.HjsonOptions;
286
import org.hjson.HjsonDsf;
287
288
// Create data with special values
289
JsonObject data = new JsonObject()
290
.add("normalNumber", 42)
291
.add("infinity", JsonValue.valueOf(Double.POSITIVE_INFINITY))
292
.add("hexValue", JsonValue.valueOf(255))
293
.add("nanValue", JsonValue.valueOf(Double.NaN));
294
295
// Default formatting
296
String defaultOutput = data.toString(Stringify.HJSON);
297
System.out.println("Default:");
298
System.out.println(defaultOutput);
299
300
// Custom formatting with DSF providers
301
HjsonOptions options = new HjsonOptions();
302
options.setDsfProviders(new IHjsonDsfProvider[] {
303
HjsonDsf.math(), // Format mathematical constants
304
HjsonDsf.hex(true) // Format numbers as hexadecimal when appropriate
305
});
306
307
String customOutput = data.toString(options);
308
System.out.println("\nWith DSF providers:");
309
System.out.println(customOutput);
310
// Output may include:
311
// {
312
// normalNumber: 42
313
// infinity: +Inf
314
// hexValue: 0xFF
315
// nanValue: NaN
316
// }
317
```
318
319
## File I/O Patterns
320
321
### Writing Configuration Files
322
323
```java
324
import org.hjson.JsonObject;
325
import org.hjson.JsonArray;
326
import org.hjson.Stringify;
327
import java.io.FileWriter;
328
import java.io.IOException;
329
import java.nio.file.Paths;
330
331
public class ConfigWriter {
332
public static void writeAppConfig() {
333
JsonObject config = new JsonObject()
334
.add("app", new JsonObject()
335
.add("name", "My Application")
336
.add("version", "1.2.0")
337
.add("port", 8080))
338
.add("database", new JsonObject()
339
.add("host", "localhost")
340
.add("port", 5432)
341
.add("name", "myapp_db"))
342
.add("features", new JsonArray()
343
.add("authentication")
344
.add("logging")
345
.add("metrics"));
346
347
// Write human-readable configuration
348
try (FileWriter writer = new FileWriter("config.hjson")) {
349
config.writeTo(writer, Stringify.HJSON);
350
System.out.println("Configuration written to config.hjson");
351
} catch (IOException e) {
352
System.err.println("Failed to write config: " + e.getMessage());
353
}
354
355
// Write JSON for production deployment
356
try (FileWriter writer = new FileWriter("config.json")) {
357
config.writeTo(writer, Stringify.FORMATTED);
358
System.out.println("JSON configuration written to config.json");
359
} catch (IOException e) {
360
System.err.println("Failed to write JSON config: " + e.getMessage());
361
}
362
}
363
}
364
```
365
366
### API Response Generation
367
368
```java
369
import org.hjson.JsonObject;
370
import org.hjson.JsonArray;
371
import org.hjson.Stringify;
372
import java.io.StringWriter;
373
374
public class ApiResponseGenerator {
375
public static String generateUserListResponse(List<User> users) {
376
JsonObject response = new JsonObject()
377
.add("status", "success")
378
.add("total", users.size())
379
.add("page", 1)
380
.add("data", new JsonArray());
381
382
JsonArray userArray = response.get("data").asArray();
383
for (User user : users) {
384
JsonObject userObj = new JsonObject()
385
.add("id", user.getId())
386
.add("name", user.getName())
387
.add("email", user.getEmail())
388
.add("active", user.isActive());
389
userArray.add(userObj);
390
}
391
392
// Return compact JSON for API responses
393
return response.toString(Stringify.PLAIN);
394
}
395
396
public static void writeResponseToStream(JsonObject response, Writer writer)
397
throws IOException {
398
// Stream the response directly without loading into memory
399
response.writeTo(writer, Stringify.PLAIN);
400
}
401
}
402
```
403
404
### Large Data Export
405
406
```java
407
import org.hjson.JsonArray;
408
import org.hjson.JsonObject;
409
import java.io.BufferedWriter;
410
import java.io.FileWriter;
411
import java.io.IOException;
412
413
public class DataExporter {
414
public static void exportLargeDataset(List<DataRecord> records, String filename)
415
throws IOException {
416
417
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
418
// Write array opening
419
writer.write("[\n");
420
421
for (int i = 0; i < records.size(); i++) {
422
DataRecord record = records.get(i);
423
JsonObject obj = new JsonObject()
424
.add("id", record.getId())
425
.add("timestamp", record.getTimestamp())
426
.add("data", record.getData());
427
428
// Write formatted JSON for readability
429
String jsonStr = obj.toString(Stringify.FORMATTED);
430
431
// Indent the object content
432
String[] lines = jsonStr.split("\n");
433
for (String line : lines) {
434
writer.write(" " + line + "\n");
435
}
436
437
// Add comma except for last element
438
if (i < records.size() - 1) {
439
writer.write(",\n");
440
}
441
}
442
443
writer.write("]\n");
444
}
445
}
446
}
447
```
448
449
## Performance Considerations
450
451
### Memory Usage
452
453
```java
454
// For large objects, prefer streaming over string conversion
455
JsonObject largeObject = createLargeObject();
456
457
// Memory-efficient: streams directly to output
458
try (FileWriter writer = new FileWriter("large-output.json")) {
459
largeObject.writeTo(writer, Stringify.PLAIN);
460
}
461
462
// Memory-intensive: loads entire string into memory
463
String largeString = largeObject.toString(Stringify.PLAIN);
464
Files.write(Paths.get("large-output.json"), largeString.getBytes());
465
```
466
467
### Output Format Performance
468
469
```java
470
// Performance ranking (fastest to slowest):
471
// 1. PLAIN - minimal processing, no whitespace
472
String fastest = value.toString(Stringify.PLAIN);
473
474
// 2. FORMATTED - adds indentation and line breaks
475
String medium = value.toString(Stringify.FORMATTED);
476
477
// 3. HJSON - most processing, format conversion
478
String slowest = value.toString(Stringify.HJSON);
479
480
// For high-performance scenarios, use PLAIN format
481
// For development and debugging, use FORMATTED or HJSON
482
```
483
484
## Thread Safety and Best Practices
485
486
- **Thread Safety**: Serialization methods are thread-safe for reading immutable JsonValue objects
487
- **Stream Management**: Always use try-with-resources for proper stream cleanup
488
- **Error Handling**: Handle IOException appropriately when writing to streams
489
- **Format Selection**: Choose format based on use case (PLAIN for APIs, HJSON for configs)
490
- **Memory Efficiency**: Use streaming methods for large data sets
491
- **Character Encoding**: Ensure proper encoding when writing to files
492
- **Buffer Size**: Use BufferedWriter for better performance with frequent writes
493
494
## Error Handling Patterns
495
496
```java
497
import java.io.IOException;
498
import java.io.FileWriter;
499
500
public void safeWrite(JsonValue value, String filename) {
501
try (FileWriter writer = new FileWriter(filename)) {
502
value.writeTo(writer, Stringify.FORMATTED);
503
} catch (IOException e) {
504
// Log error and handle gracefully
505
logger.error("Failed to write JSON to file: " + filename, e);
506
throw new RuntimeException("Unable to save data", e);
507
}
508
}
509
510
public String safeToString(JsonValue value, Stringify format) {
511
try {
512
return value.toString(format);
513
} catch (Exception e) {
514
// Fallback to basic format on error
515
logger.warn("Failed to format with " + format + ", using PLAIN", e);
516
return value.toString(Stringify.PLAIN);
517
}
518
}
519
```