0
# JSON Processing
1
2
Client-side JSON encoding and decoding with support for custom marshalling, type-aware conversion, and integration with the Errai type system.
3
4
## Capabilities
5
6
### JSON Encoder
7
8
Client-side JSON encoder with support for custom marshalling and type metadata tracking.
9
10
```java { .api }
11
/**
12
* Client-side JSON encoder with support for custom marshalling
13
*/
14
public class JSONEncoderCli {
15
/**
16
* Encode object to JSON string
17
* @param v - Object to encode
18
* @return JSON string representation
19
*/
20
public String encode(Object v);
21
22
/**
23
* Encode map to JSON with marshalling metadata
24
* @param map - Map to encode
25
* @return JSON string with type metadata
26
*/
27
public String encodeMap(Map<Object, Object> map);
28
29
/**
30
* Get types that were marshalled during encoding
31
* @return Map of property names to marshalled type names
32
*/
33
public Map<String, String> getMarshalledTypes();
34
}
35
```
36
37
**Supported Types:**
38
- `null` → `"null"`
39
- `String` → Quoted and escaped JSON string
40
- `Number`, `Boolean` → Direct JSON representation
41
- `Collection` → JSON array
42
- `Map` → JSON object
43
- `Object[]` → JSON array
44
- `Serializable` objects → Custom marshalling (if marshaller available)
45
46
**Usage Examples:**
47
48
```java
49
import org.jboss.errai.common.client.json.JSONEncoderCli;
50
import java.util.*;
51
52
JSONEncoderCli encoder = new JSONEncoderCli();
53
54
// Encode primitive values
55
String nullJson = encoder.encode(null); // "null"
56
String stringJson = encoder.encode("hello"); // "\"hello\""
57
String numberJson = encoder.encode(42); // "42"
58
String boolJson = encoder.encode(true); // "true"
59
60
// Encode collections
61
List<String> list = Arrays.asList("a", "b", "c");
62
String arrayJson = encoder.encode(list); // "[\"a\",\"b\",\"c\"]"
63
64
// Encode maps
65
Map<String, Object> map = new HashMap<>();
66
map.put("name", "John");
67
map.put("age", 30);
68
String objectJson = encoder.encode(map); // "{\"name\":\"John\",\"age\":30}"
69
70
// Check marshalled types
71
Map<String, String> marshalledTypes = encoder.getMarshalledTypes();
72
```
73
74
### JSON Decoder
75
76
Client-side JSON decoder with support for custom demarshalling and type restoration.
77
78
```java { .api }
79
/**
80
* Client-side JSON decoder with support for custom demarshalling
81
*/
82
public class JSONDecoderCli {
83
/**
84
* Decode JSON string to object
85
* @param value - JSON string to decode
86
* @return Decoded object (Map for objects, List for arrays, primitives for values)
87
*/
88
public Object decode(Object value);
89
}
90
```
91
92
**Decoding Behavior:**
93
- JSON strings → Java `String`
94
- JSON numbers → Java `Double`
95
- JSON booleans → Java `Boolean`
96
- JSON null → Java `null`
97
- JSON objects → Java `Map<String, Object>`
98
- JSON arrays → Java `List<Object>`
99
- Objects with `__EncodedType` → Custom demarshalling (if demarshaller available)
100
101
**Usage Examples:**
102
103
```java
104
import org.jboss.errai.common.client.json.JSONDecoderCli;
105
106
JSONDecoderCli decoder = new JSONDecoderCli();
107
108
// Decode primitive values
109
Object nullObj = decoder.decode("null"); // null
110
Object stringObj = decoder.decode("\"hello\""); // "hello"
111
Object numberObj = decoder.decode("42"); // 42.0 (Double)
112
Object boolObj = decoder.decode("true"); // true
113
114
// Decode arrays
115
Object arrayObj = decoder.decode("[1, 2, 3]"); // List<Object> containing [1.0, 2.0, 3.0]
116
117
// Decode objects
118
Object objectObj = decoder.decode("{\"name\":\"John\",\"age\":30}");
119
// Map<String, Object> containing {"name": "John", "age": 30.0}
120
```
121
122
### Custom Marshalling Integration
123
124
The JSON encoder integrates with the marshalling system to handle `Serializable` objects.
125
126
**Custom Marshalling Process:**
127
128
1. When encoding a `Serializable` object, the encoder checks `TypeMarshallers.hasMarshaller()`
129
2. If a marshaller exists, it uses `TypeMarshallers.getMarshaller().marshall()`
130
3. The marshalled result is included in JSON output
131
4. Type metadata is tracked in `getMarshalledTypes()`
132
133
**Custom Demarshalling Process:**
134
135
1. When decoding objects with `__EncodedType` property, the decoder extracts the class name
136
2. It checks `TypeDemarshallers.hasDemarshaller()` for the class
137
3. If a demarshaller exists, it uses `TypeDemarshallers.getDemarshaller().demarshall()`
138
4. Otherwise, it throws a `RuntimeException`
139
140
**Usage Example:**
141
142
```java
143
import org.jboss.errai.common.client.types.*;
144
import org.jboss.errai.common.client.json.*;
145
import java.io.Serializable;
146
147
// Custom class
148
public class Person implements Serializable {
149
public String name;
150
public int age;
151
152
public Person(String name, int age) {
153
this.name = name;
154
this.age = age;
155
}
156
}
157
158
// Custom marshaller
159
public class PersonMarshaller implements Marshaller<Person> {
160
public String marshall(Person person) {
161
return "{\"name\":\"" + person.name + "\",\"age\":" + person.age +
162
",\"__EncodedType\":\"Person\"}";
163
}
164
}
165
166
// Custom demarshaller
167
public class PersonDemarshaller implements Demarshaller<Person> {
168
public Person demarshall(JSONObject o) {
169
String name = o.get("name").isString().stringValue();
170
int age = (int) o.get("age").isNumber().doubleValue();
171
return new Person(name, age);
172
}
173
}
174
175
// Registration and usage
176
TypeMarshallers.addMarshaller(Person.class, new PersonMarshaller());
177
TypeDemarshallers.addDemarshaller(Person.class, new PersonDemarshaller());
178
179
JSONEncoderCli encoder = new JSONEncoderCli();
180
JSONDecoderCli decoder = new JSONDecoderCli();
181
182
Person person = new Person("Alice", 25);
183
String json = encoder.encode(person);
184
Person decoded = (Person) decoder.decode(json);
185
```
186
187
## Error Handling
188
189
**Encoding Errors:**
190
- `RuntimeException` thrown for objects without available marshallers
191
- Non-serializable objects cause encoding to defer (return null)
192
193
**Decoding Errors:**
194
- `RuntimeException` thrown for unknown JSON encodings
195
- `RuntimeException` thrown for missing demarshallers with detailed error message
196
- GWT.log() used for debugging missing demarshallers
197
198
**Example Error Handling:**
199
200
```java
201
import org.jboss.errai.common.client.json.*;
202
203
JSONEncoderCli encoder = new JSONEncoderCli();
204
JSONDecoderCli decoder = new JSONDecoderCli();
205
206
try {
207
// This will throw RuntimeException if no marshaller is registered
208
String json = encoder.encode(new UnknownSerializableClass());
209
} catch (RuntimeException e) {
210
// Handle marshalling error
211
System.err.println("Marshalling failed: " + e.getMessage());
212
}
213
214
try {
215
// This will throw RuntimeException if encoded type has no demarshaller
216
Object obj = decoder.decode("{\"__EncodedType\":\"UnknownClass\"}");
217
} catch (RuntimeException e) {
218
// Handle demarshalling error
219
System.err.println("Demarshalling failed: " + e.getMessage());
220
}
221
```
222
223
## Integration with Type System
224
225
The JSON processing classes integrate seamlessly with the type conversion system:
226
227
```java
228
import org.jboss.errai.common.client.types.JSONTypeHelper;
229
import com.google.gwt.json.client.JSONParser;
230
231
// Convert JSON to typed objects using type handlers
232
JSONValue jsonValue = JSONParser.parseStrict("[1, 2, 3]");
233
List<Integer> typedList = JSONTypeHelper.convert(jsonValue, List.class);
234
235
// Use JSON helper for encoding
236
String encoded = JSONTypeHelper.encodeHelper("text"); // "\"text\""
237
```