0
# JSON Processing
1
2
Apache ActiveMQ Artemis Commons provides a complete JSON API implementation through shaded Jakarta JSON and Apache Johnzon dependencies. The API provides full JSON processing capabilities including parsing, building, and manipulation of JSON objects and arrays.
3
4
## Core JSON Interfaces
5
6
### JsonValue
7
8
Base interface for all JSON values.
9
10
```java { .api }
11
interface JsonValue {
12
// JSON value types
13
enum ValueType {
14
ARRAY, OBJECT, STRING, NUMBER, TRUE, FALSE, NULL
15
}
16
17
// Constants for common values
18
JsonValue TRUE = /* ... */;
19
JsonValue FALSE = /* ... */;
20
JsonValue NULL = /* ... */;
21
22
// Core methods
23
ValueType getValueType();
24
String toString();
25
}
26
```
27
28
### JsonObject
29
30
JSON object representation with Map-like interface.
31
32
```java { .api }
33
interface JsonObject extends JsonValue, Map<String, JsonValue> {
34
// Type-safe getters for nested JSON values
35
JsonObject getJsonObject(String name);
36
JsonArray getJsonArray(String name);
37
JsonNumber getJsonNumber(String name);
38
JsonString getJsonString(String name);
39
40
// Native type getters
41
String getString(String name);
42
String getString(String name, String defaultValue);
43
int getInt(String name);
44
int getInt(String name, int defaultValue);
45
boolean getBoolean(String name);
46
boolean getBoolean(String name, boolean defaultValue);
47
48
// Utility methods
49
boolean isNull(String name);
50
boolean containsKey(String name);
51
}
52
```
53
54
### JsonArray
55
56
JSON array representation with List-like interface.
57
58
```java { .api }
59
interface JsonArray extends JsonValue, List<JsonValue> {
60
// Type-safe getters by index
61
JsonObject getJsonObject(int index);
62
JsonArray getJsonArray(int index);
63
JsonNumber getJsonNumber(int index);
64
JsonString getJsonString(int index);
65
66
// Native type getters by index
67
String getString(int index);
68
String getString(int index, String defaultValue);
69
int getInt(int index);
70
int getInt(int index, int defaultValue);
71
boolean getBoolean(int index);
72
boolean getBoolean(int index, boolean defaultValue);
73
74
// Utility methods
75
boolean isNull(int index);
76
<T> List<T> getValuesAs(Class<T> clazz);
77
<T, K extends JsonValue> List<T> getValuesAs(Function<K, T> func);
78
}
79
```
80
81
### JsonString and JsonNumber
82
83
```java { .api }
84
interface JsonString extends JsonValue {
85
String getString();
86
}
87
88
interface JsonNumber extends JsonValue {
89
boolean isIntegral();
90
int intValue();
91
long longValue();
92
BigInteger bigIntegerValue();
93
double doubleValue();
94
BigDecimal bigDecimalValue();
95
}
96
```
97
98
## JSON Builders
99
100
### JsonObjectBuilder
101
102
Builder for creating JSON objects.
103
104
```java { .api }
105
interface JsonObjectBuilder {
106
// Add methods for different value types
107
JsonObjectBuilder add(String name, JsonValue value);
108
JsonObjectBuilder add(String name, String value);
109
JsonObjectBuilder add(String name, BigInteger value);
110
JsonObjectBuilder add(String name, BigDecimal value);
111
JsonObjectBuilder add(String name, int value);
112
JsonObjectBuilder add(String name, long value);
113
JsonObjectBuilder add(String name, double value);
114
JsonObjectBuilder add(String name, boolean value);
115
116
// Add nested builders
117
JsonObjectBuilder add(String name, JsonObjectBuilder builder);
118
JsonObjectBuilder add(String name, JsonArrayBuilder builder);
119
120
// Null value and manipulation
121
JsonObjectBuilder addNull(String name);
122
JsonObjectBuilder addAll(JsonObjectBuilder builder);
123
JsonObjectBuilder remove(String name);
124
125
// Build final object
126
JsonObject build();
127
}
128
```
129
130
### JsonArrayBuilder
131
132
Builder for creating JSON arrays.
133
134
```java { .api }
135
interface JsonArrayBuilder {
136
// Add methods for different value types
137
JsonArrayBuilder add(JsonValue value);
138
JsonArrayBuilder add(String value);
139
JsonArrayBuilder add(BigInteger value);
140
JsonArrayBuilder add(BigDecimal value);
141
JsonArrayBuilder add(int value);
142
JsonArrayBuilder add(long value);
143
JsonArrayBuilder add(double value);
144
JsonArrayBuilder add(boolean value);
145
146
// Add nested builders
147
JsonArrayBuilder add(JsonObjectBuilder builder);
148
JsonArrayBuilder add(JsonArrayBuilder builder);
149
150
// Null value and manipulation
151
JsonArrayBuilder addNull();
152
JsonArrayBuilder addAll(JsonArrayBuilder builder);
153
JsonArrayBuilder add(int index, JsonValue value);
154
JsonArrayBuilder set(int index, JsonValue value);
155
JsonArrayBuilder remove(int index);
156
157
// Build final array
158
JsonArray build();
159
}
160
```
161
162
## JSON Factory and Utilities
163
164
### JsonLoader
165
166
Factory class for creating JSON objects, arrays, and builders.
167
168
```java { .api }
169
class JsonLoader {
170
// Reading JSON from sources
171
static JsonObject readObject(Reader reader);
172
static JsonArray readArray(Reader reader);
173
static JsonObject readObject(InputStream stream);
174
static JsonArray readArray(InputStream stream);
175
static JsonObject readObject(String jsonString);
176
static JsonArray readArray(String jsonString);
177
178
// Creating builders
179
static JsonObjectBuilder createObjectBuilder();
180
static JsonArrayBuilder createArrayBuilder();
181
static JsonObjectBuilder createObjectBuilder(JsonObject object);
182
static JsonArrayBuilder createArrayBuilder(JsonArray array);
183
}
184
```
185
186
## Usage Examples
187
188
### Creating JSON Objects
189
190
```java
191
import org.apache.activemq.artemis.utils.JsonLoader;
192
import org.apache.activemq.artemis.json.*;
193
194
// Create JSON object using builder
195
JsonObject config = JsonLoader.createObjectBuilder()
196
.add("name", "messageQueue")
197
.add("durable", true)
198
.add("maxConsumers", 10)
199
.add("address", "orders.processing")
200
.add("properties", JsonLoader.createObjectBuilder()
201
.add("priority", 5)
202
.add("timeout", 30000)
203
.addNull("description"))
204
.build();
205
206
// Convert to string
207
String jsonString = config.toString();
208
```
209
210
### Creating JSON Arrays
211
212
```java
213
// Create JSON array of queue configurations
214
JsonArray queues = JsonLoader.createArrayBuilder()
215
.add(JsonLoader.createObjectBuilder()
216
.add("name", "highPriority")
217
.add("maxConsumers", 5)
218
.add("ringSize", 1000))
219
.add(JsonLoader.createObjectBuilder()
220
.add("name", "lowPriority")
221
.add("maxConsumers", 2)
222
.add("ringSize", 500))
223
.addNull() // placeholder
224
.add("simpleQueueName")
225
.build();
226
227
// Process array elements
228
for (int i = 0; i < queues.size(); i++) {
229
if (!queues.isNull(i)) {
230
JsonValue value = queues.get(i);
231
if (value.getValueType() == JsonValue.ValueType.OBJECT) {
232
JsonObject queueConfig = queues.getJsonObject(i);
233
String name = queueConfig.getString("name");
234
int maxConsumers = queueConfig.getInt("maxConsumers", 1);
235
// Process queue configuration
236
}
237
}
238
}
239
```
240
241
### Reading JSON from Strings
242
243
```java
244
// Parse JSON string
245
String jsonData = """
246
{
247
"server": {
248
"host": "localhost",
249
"port": 61616,
250
"ssl": false
251
},
252
"queues": [
253
{"name": "orders", "durable": true},
254
{"name": "notifications", "durable": false}
255
],
256
"maxConnections": 100
257
}
258
""";
259
260
JsonObject serverConfig = JsonLoader.readObject(jsonData);
261
262
// Extract nested values
263
JsonObject server = serverConfig.getJsonObject("server");
264
String host = server.getString("host");
265
int port = server.getInt("port");
266
boolean ssl = server.getBoolean("ssl");
267
268
JsonArray queues = serverConfig.getJsonArray("queues");
269
int maxConnections = serverConfig.getInt("maxConnections");
270
271
// Process queues
272
for (JsonObject queue : queues.getValuesAs(JsonObject.class)) {
273
String queueName = queue.getString("name");
274
boolean durable = queue.getBoolean("durable");
275
// Configure queue
276
}
277
```
278
279
### Reading JSON from Streams
280
281
```java
282
import java.io.*;
283
284
// Read from file
285
try (FileReader reader = new FileReader("config.json")) {
286
JsonObject config = JsonLoader.readObject(reader);
287
// Process configuration
288
}
289
290
// Read from input stream
291
try (InputStream stream = getClass().getResourceAsStream("/default-config.json")) {
292
JsonObject defaultConfig = JsonLoader.readObject(stream);
293
// Process default configuration
294
}
295
```
296
297
### Modifying Existing JSON
298
299
```java
300
// Start with existing JSON object
301
JsonObject original = JsonLoader.readObject(existingJsonString);
302
303
// Create modified version using builder
304
JsonObject modified = JsonLoader.createObjectBuilder(original)
305
.add("lastModified", System.currentTimeMillis())
306
.add("version", "2.0")
307
.remove("deprecated")
308
.build();
309
310
// Merge with additional properties
311
JsonObject extended = JsonLoader.createObjectBuilder(modified)
312
.addAll(JsonLoader.createObjectBuilder()
313
.add("newFeature", true)
314
.add("migrationRequired", false))
315
.build();
316
```
317
318
### Type-Safe Value Extraction
319
320
```java
321
JsonObject data = JsonLoader.readObject(jsonString);
322
323
// Safe extraction with defaults
324
String name = data.getString("name", "defaultQueue");
325
int priority = data.getInt("priority", 0);
326
boolean enabled = data.getBoolean("enabled", true);
327
328
// Check for null values
329
if (!data.isNull("description")) {
330
String description = data.getString("description");
331
// Use description
332
}
333
334
// Safe nested access
335
if (data.containsKey("metadata")) {
336
JsonObject metadata = data.getJsonObject("metadata");
337
if (metadata.containsKey("tags")) {
338
JsonArray tags = metadata.getJsonArray("tags");
339
List<String> tagList = tags.getValuesAs(JsonString.class)
340
.stream()
341
.map(JsonString::getString)
342
.collect(Collectors.toList());
343
}
344
}
345
```
346
347
### Complex JSON Construction
348
349
```java
350
// Build complex nested JSON structure
351
JsonObject complexConfig = JsonLoader.createObjectBuilder()
352
.add("version", "1.0")
353
.add("timestamp", System.currentTimeMillis())
354
.add("server", JsonLoader.createObjectBuilder()
355
.add("host", "broker.example.com")
356
.add("ports", JsonLoader.createArrayBuilder()
357
.add(61616)
358
.add(61617)
359
.add(5445))
360
.add("security", JsonLoader.createObjectBuilder()
361
.add("enabled", true)
362
.add("protocols", JsonLoader.createArrayBuilder()
363
.add("TLS")
364
.add("SASL"))))
365
.add("queues", JsonLoader.createArrayBuilder()
366
.add(JsonLoader.createObjectBuilder()
367
.add("name", "orders")
368
.add("address", "orders.processing")
369
.add("durable", true)
370
.add("consumers", JsonLoader.createObjectBuilder()
371
.add("max", 10)
372
.add("exclusive", false)))
373
.add(JsonLoader.createObjectBuilder()
374
.add("name", "notifications")
375
.add("address", "notifications.email")
376
.add("durable", false)
377
.add("consumers", JsonLoader.createObjectBuilder()
378
.add("max", 1)
379
.add("exclusive", true))))
380
.build();
381
382
// Serialize to formatted JSON
383
String prettyJson = complexConfig.toString();
384
```
385
386
## Integration with ActiveMQ Configuration
387
388
### QueueConfiguration JSON Integration
389
390
```java
391
import org.apache.activemq.artemis.api.core.QueueConfiguration;
392
393
// QueueConfiguration can be serialized to/from JSON
394
QueueConfiguration queue = QueueConfiguration.of("myQueue")
395
.setDurable(true)
396
.setMaxConsumers(5);
397
398
// Convert to JSON using built-in method
399
String queueJson = queue.toJSON();
400
401
// Parse back from JSON
402
QueueConfiguration restored = QueueConfiguration.fromJSON(queueJson);
403
404
// The JSON uses the same structure as the JSON API
405
JsonObject queueJsonObj = JsonLoader.readObject(queueJson);
406
String queueName = queueJsonObj.getString("name");
407
boolean durable = queueJsonObj.getBoolean("durable");
408
```
409
410
### Configuration File Processing
411
412
```java
413
// Process configuration files with multiple queue definitions
414
JsonObject config = JsonLoader.readObject(configFileReader);
415
JsonArray queues = config.getJsonArray("queues");
416
417
List<QueueConfiguration> queueConfigs = new ArrayList<>();
418
for (JsonObject queueJson : queues.getValuesAs(JsonObject.class)) {
419
// Convert JSON to QueueConfiguration
420
QueueConfiguration queueConfig = QueueConfiguration.fromJSON(queueJson.toString());
421
queueConfigs.add(queueConfig);
422
}
423
424
// Use configurations
425
for (QueueConfiguration config : queueConfigs) {
426
createQueue(config);
427
}
428
```
429
430
## Error Handling
431
432
### JSON Processing Exceptions
433
434
```java
435
try {
436
JsonObject obj = JsonLoader.readObject(malformedJson);
437
} catch (JsonException e) {
438
// Handle malformed JSON
439
logger.error("Invalid JSON format", e);
440
} catch (ClassCastException e) {
441
// Handle type mismatches
442
logger.error("JSON type mismatch", e);
443
}
444
445
// Safe value extraction
446
JsonObject data = JsonLoader.readObject(jsonString);
447
try {
448
int value = data.getInt("numericField");
449
} catch (ClassCastException e) {
450
// Field is not numeric, use default
451
int value = 0;
452
} catch (NullPointerException e) {
453
// Field doesn't exist, use default
454
int value = 0;
455
}
456
```
457
458
## Performance Considerations
459
460
### Reusing Builders
461
462
```java
463
// Reuse builders for better performance
464
JsonObjectBuilder reusableBuilder = JsonLoader.createObjectBuilder();
465
466
for (DataItem item : items) {
467
JsonObject itemJson = reusableBuilder
468
.add("id", item.getId())
469
.add("name", item.getName())
470
.add("timestamp", item.getTimestamp())
471
.build();
472
473
processItem(itemJson);
474
475
// Builder is reset after build(), ready for reuse
476
}
477
```
478
479
### Streaming for Large Data
480
481
```java
482
// For large JSON data, consider streaming approaches
483
try (JsonParser parser = Json.createParser(largeJsonStream)) {
484
while (parser.hasNext()) {
485
JsonParser.Event event = parser.next();
486
switch (event) {
487
case START_OBJECT:
488
// Process object start
489
break;
490
case KEY_NAME:
491
String key = parser.getString();
492
break;
493
case VALUE_STRING:
494
String value = parser.getString();
495
break;
496
// Handle other events
497
}
498
}
499
}
500
```