0
# JSON Output & Serialization
1
2
Comprehensive JSON serialization utilities with customizable generation, type conversion, and formatting options.
3
4
## Capabilities
5
6
### JsonOutput
7
8
Static utility class providing convenient methods for converting Java objects to JSON strings.
9
10
```java { .api }
11
/**
12
* Static utility methods for JSON serialization
13
*/
14
public class JsonOutput {
15
// Character constants for JSON structure
16
public static final char OPEN_BRACKET = '[';
17
public static final char CLOSE_BRACKET = ']';
18
public static final char OPEN_BRACE = '{';
19
public static final char CLOSE_BRACE = '}';
20
public static final char COLON = ':';
21
public static final char COMMA = ',';
22
public static final char SPACE = ' ';
23
public static final char NEW_LINE = '\n';
24
public static final char QUOTE = '"';
25
26
/** Convert primitive types to JSON */
27
public static String toJson(Boolean bool);
28
public static String toJson(Number n);
29
public static String toJson(Character c);
30
31
/** Convert String to JSON with proper escaping */
32
public static String toJson(String s);
33
34
/** Convert temporal types to ISO-8601 format */
35
public static String toJson(Date date);
36
public static String toJson(Calendar cal);
37
38
/** Convert other Java types to JSON */
39
public static String toJson(UUID uuid);
40
public static String toJson(URL url);
41
42
/** Convert Groovy-specific types to JSON */
43
public static String toJson(Closure closure);
44
public static String toJson(Expando expando);
45
46
/** Convert collections and objects to JSON */
47
public static String toJson(Map m);
48
public static String toJson(Object object);
49
50
/** Pretty-print JSON strings */
51
public static String prettyPrint(String jsonPayload);
52
public static String prettyPrint(String jsonPayload, boolean disableUnicodeEscaping);
53
54
/** Create unescaped JSON text */
55
public static JsonUnescaped unescaped(CharSequence text);
56
}
57
```
58
59
**Usage Examples:**
60
61
```java
62
import groovy.json.JsonOutput;
63
import java.util.*;
64
65
// Basic type conversion
66
String boolJson = JsonOutput.toJson(true); // "true"
67
String numJson = JsonOutput.toJson(42); // "42"
68
String strJson = JsonOutput.toJson("Hello \"World\""); // "\"Hello \\\"World\\\"\""
69
70
// Date formatting (ISO-8601)
71
Date now = new Date();
72
String dateJson = JsonOutput.toJson(now); // "2023-12-01T10:30:45+0000"
73
74
// Map/Object conversion
75
Map<String, Object> data = new HashMap<>();
76
data.put("name", "Alice");
77
data.put("age", 30);
78
data.put("active", true);
79
String mapJson = JsonOutput.toJson(data);
80
// {"name":"Alice","age":30,"active":true}
81
82
// Pretty printing
83
String compact = '{"name":"Alice","details":{"age":30,"city":"NYC"}}';
84
String pretty = JsonOutput.prettyPrint(compact);
85
/*
86
{
87
"name": "Alice",
88
"details": {
89
"age": 30,
90
"city": "NYC"
91
}
92
}
93
*/
94
95
// Unescaped content (for pre-formatted JSON)
96
String rawJson = '{"already":"formatted"}';
97
JsonOutput.JsonUnescaped unescaped = JsonOutput.unescaped(rawJson);
98
String combined = JsonOutput.toJson(Map.of("data", unescaped));
99
// {"data":{"already":"formatted"}}
100
```
101
102
### JsonUnescaped
103
104
Wrapper class for JSON content that should not be escaped during serialization.
105
106
```java { .api }
107
/**
108
* Represents unescaped JSON text that should be inserted verbatim
109
*/
110
public static class JsonUnescaped {
111
/** Constructor with text content */
112
public JsonUnescaped(CharSequence text);
113
114
/** Get the unescaped text */
115
public CharSequence getText();
116
117
/** String representation */
118
public String toString();
119
}
120
```
121
122
### JsonGenerator Interface
123
124
Interface for customizable JSON generation with advanced options and type conversion.
125
126
```java { .api }
127
/**
128
* Interface for customizable JSON generation
129
*/
130
public interface JsonGenerator {
131
/** Convert object to JSON string */
132
public String toJson(Object object);
133
134
/** Check if field name should be excluded */
135
public boolean isExcludingFieldsNamed(String name);
136
137
/** Check if value should be excluded */
138
public boolean isExcludingValues(Object value);
139
}
140
```
141
142
### JsonGenerator.Options
143
144
Builder class for configuring JsonGenerator instances with comprehensive customization options.
145
146
```java { .api }
147
/**
148
* Builder for JsonGenerator configuration
149
*/
150
public static class Options {
151
/** Constructor */
152
public Options();
153
154
/** Exclude null values from JSON output */
155
public Options excludeNulls();
156
157
/** Disable Unicode character escaping */
158
public Options disableUnicodeEscaping();
159
160
/** Set custom date format pattern */
161
public Options dateFormat(String format);
162
public Options dateFormat(String format, Locale locale);
163
164
/** Set timezone for date formatting */
165
public Options timezone(String timezone);
166
167
/** Add custom type converter */
168
public Options addConverter(Converter converter);
169
public <T> Options addConverter(Class<T> type, Closure<?> closure);
170
public <T> Options addConverter(Closure<Boolean> predicate, Closure<?> converter);
171
172
/** Exclude fields by name */
173
public Options excludeFieldsByName(CharSequence... fieldNames);
174
public Options excludeFieldsByName(Iterable<? extends CharSequence> fieldNames);
175
176
/** Exclude fields by type */
177
public Options excludeFieldsByType(Class<?>... types);
178
public Options excludeFieldsByType(Iterable<Class<?>> types);
179
180
/** Exclude specific values from output */
181
public Options excludeFieldsByValue(Object... values);
182
public Options excludeFieldsByValue(Iterable<?> values);
183
184
/** Build configured JsonGenerator */
185
public JsonGenerator build();
186
}
187
```
188
189
**Usage Examples:**
190
191
```java
192
import groovy.json.JsonGenerator;
193
import java.time.LocalDateTime;
194
195
// Custom generator with exclusions and formatting
196
JsonGenerator generator = new JsonGenerator.Options()
197
.excludeNulls()
198
.dateFormat("yyyy-MM-dd HH:mm:ss")
199
.timezone("America/New_York")
200
.excludeFieldsByName("password", "secret")
201
.excludeFieldsByType(Class.class)
202
.disableUnicodeEscaping()
203
.build();
204
205
Map<String, Object> user = Map.of(
206
"name", "Alice",
207
"password", "secret123", // Will be excluded
208
"lastLogin", new Date(),
209
"metadata", null // Will be excluded
210
);
211
212
String json = generator.toJson(user);
213
// {"name":"Alice","lastLogin":"2023-12-01 10:30:45"}
214
215
// Custom converter for specific types
216
JsonGenerator customGenerator = new JsonGenerator.Options()
217
.addConverter(LocalDateTime.class, { obj, key ->
218
return obj.toString() + "Z";
219
})
220
.addConverter({ type -> type.getName().startsWith("com.myapp") }, { obj, key ->
221
return obj.getId(); // Convert custom objects to just their ID
222
})
223
.build();
224
```
225
226
### JsonGenerator.Converter Interface
227
228
Interface for implementing custom type conversions during JSON generation.
229
230
```java { .api }
231
/**
232
* Interface for custom type conversion during JSON generation
233
*/
234
interface Converter {
235
/** Check if this converter handles the given type */
236
boolean handles(Class<?> type);
237
238
/** Convert the object to a JSON-serializable form */
239
Object convert(Object value, String key);
240
}
241
```
242
243
### DefaultJsonGenerator
244
245
Default implementation of JsonGenerator providing full customization support.
246
247
```java { .api }
248
/**
249
* Default JsonGenerator implementation with full customization support
250
*/
251
public class DefaultJsonGenerator implements JsonGenerator {
252
// Constructor is package-private, use JsonGenerator.Options.build()
253
254
/** Convert object to JSON (implements JsonGenerator) */
255
public String toJson(Object object);
256
257
/** Check field name exclusion (implements JsonGenerator) */
258
public boolean isExcludingFieldsNamed(String name);
259
260
/** Check value exclusion (implements JsonGenerator) */
261
public boolean isExcludingValues(Object value);
262
}
263
```
264
265
## Advanced Serialization Patterns
266
267
### Custom Date Formatting
268
269
```java
270
// Multiple date format scenarios
271
JsonGenerator usFormat = new JsonGenerator.Options()
272
.dateFormat("MM/dd/yyyy HH:mm:ss", Locale.US)
273
.timezone("America/Chicago")
274
.build();
275
276
JsonGenerator isoFormat = new JsonGenerator.Options()
277
.dateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
278
.timezone("UTC")
279
.build();
280
281
Date timestamp = new Date();
282
String usJson = usFormat.toJson(Map.of("created", timestamp));
283
String isoJson = isoFormat.toJson(Map.of("created", timestamp));
284
```
285
286
### Field Filtering and Security
287
288
```java
289
// Exclude sensitive fields and types
290
JsonGenerator secureGenerator = new JsonGenerator.Options()
291
.excludeFieldsByName("password", "secret", "token", "key")
292
.excludeFieldsByType(
293
java.security.PrivateKey.class,
294
javax.crypto.SecretKey.class
295
)
296
.excludeNulls()
297
.build();
298
299
// Safe serialization of user data
300
Map<String, Object> userData = getUserData();
301
String safeJson = secureGenerator.toJson(userData);
302
```
303
304
### Complex Type Conversion
305
306
```java
307
// Convert custom business objects
308
JsonGenerator businessGenerator = new JsonGenerator.Options()
309
.addConverter(Money.class, { money, key ->
310
return Map.of(
311
"amount", money.getAmount().toString(),
312
"currency", money.getCurrency().getCurrencyCode()
313
);
314
})
315
.addConverter(Address.class, { address, key ->
316
return address.getFormattedAddress();
317
})
318
.addConverter({ type ->
319
return type.isAnnotationPresent(JsonSerializable.class);
320
}, { obj, key ->
321
return obj.toJsonMap();
322
})
323
.build();
324
```
325
326
### Performance Optimization
327
328
```java
329
// Optimized generator for high-throughput scenarios
330
JsonGenerator optimizedGenerator = new JsonGenerator.Options()
331
.disableUnicodeEscaping() // Faster but less compatible
332
.build();
333
334
// Reuse generator instances
335
private static final JsonGenerator SHARED_GENERATOR =
336
new JsonGenerator.Options().excludeNulls().build();
337
338
public String toJson(Object obj) {
339
return SHARED_GENERATOR.toJson(obj);
340
}
341
```
342
343
## Error Handling
344
345
JSON serialization can fail with various exceptions:
346
347
```java
348
try {
349
String json = JsonOutput.toJson(problematicObject);
350
} catch (StackOverflowError e) {
351
// Circular reference detected
352
System.err.println("Circular reference in object graph");
353
} catch (Exception e) {
354
// Other serialization errors
355
System.err.println("JSON serialization failed: " + e.getMessage());
356
}
357
```