Interface JSON
- All Superinterfaces:
Bytes
JSON is "JavaScript Object Notation", a lightweight data-interchange format. See www.json.org.
To create an instance from a JSON string, obtain a JSONDataType
implementation from
Diffusion.dataTypes().json() and call
JSONDataType.fromJsonString(String).
The toJsonString() method can be used to retrieve this value as a
JSON string. Applications can use a JSON library such as Jackson to create and
interpret the JSON data represented as a string.
CBOR representation
Internally the value is stored and transmitted not as a JSON string, but in CBOR format to reduce memory and network overhead. CBOR (Concise Binary Object Representation) is a standardized format for binary representation of structured data defined by RFC 7049. See www.cbor.io.
Rather than working with JSON strings it is possible, and usually preferable, for applications to work directly with the underlying CBOR-format binary representation. This avoids creating intermediate JSON strings, and allows access to CBOR features such as the byte string data type.
Each JSON value is represented as a single CBOR data item. CBOR supports
composite data types just like JSON, so this data item can be an array or a
map of other data items. The JSON null value is represented by the
CBOR Null value.
A particular advantage of working directly with the CBOR-format data is that binary data can be written to the value as a data item using the CBOR byte string type. The data item will be stored as part of the JSON value in binary form and transmitted without further conversion.
Working with CBOR data
We recommend Jackson's jackson- dataformat-cbor as a mature library for generating and parsing CBOR-format binary data.
To create an instance from a CBOR format byte array, call
JSONDataType.readValue(byte[]). The byte array must contain a single
CBOR data item, otherwise, an InvalidDataException will be thrown
when the data is first parsed. To convert an instance to CBOR format, use
Bytes.asInputStream() or
JSONDataType.writeValue(JSON, OutputStream).
Here is an example of using jackson-dataformat-cbor to parse a CBOR
map of text values.
Map<String, String> parseMap(JSON value) throws IOException {
CBORFactory factory = new CBORFactory();
CBORParser parser = factory.createParser(value.asInputStream());
if (parser.nextToken() != JsonToken.START_OBJECT) {
return Collections.emptyMap();
}
Map<String, String> result = new HashMap<>();
while (true) {
String key = parser.nextFieldName();
if (key == null) {
return result;
}
result.put(key, parser.nextTextValue());
}
}
Parsing is straightforward for simple structures, but with more complex
structures it can become unwieldy. For a higher-level interface, a binding
library such as jackson-databind can
be used to map CBOR data to and from instances of application Java classes.
Here is an example of using jackson-dataformat-cbor and
jackson-databind to parse a JSON object of text values from the CBOR
binary data.
// mapper and factory can be reused
private ObjectMapper mapper = new ObjectMapper();
private CBORFactory factory = new CBORFactory();
Map<String, String> parseObject(JSON value) throws IOException {
CBORParser parser = factory.createParser(value.asInputStream());
return (Map<String, String>) mapper.readValue(parser, Map.class);
}
CBOR limitations
The mapping from a JSON string to and from CBOR-format binary data is mostly straightforward, but there are a few limitations. In particular:
- Non-string keys are not supported.
- Precision may be lost converting numbers from JSON to CBOR. For example,
a JSON string can precisely represent the decimal fraction
0.3as text. The defaultJSONDataType.fromJsonString(String)conversion will convert this imprecisely as a floating-point number. Applications can work around this limitation by reading and writing CBOR data directly to a decimal fraction tagged array.
- Since:
- 5.7
- Author:
- DiffusionData Limited
-
Method Summary
Modifier and TypeMethodDescriptionapply(BinaryDelta delta) Apply a binary delta to this JSON value to create a new value.binaryDiff(JSON original) Compare this JSON value with an earlier version to create a binary delta.Compare this JSON value with an earlier version to calculate a structural delta.validate()Check whether this instance is valid.Methods inherited from interface com.pushtechnology.diffusion.datatype.Bytes
asInputStream, copyTo, length, toByteArray
-
Method Details
-
binaryDiff
Compare this JSON value with an earlier version to create a binary delta.Convenient equivalent to
Diffusion.dataTypes().json().binaryDeltaType().diff(original, this).- Returns:
- a delta representing the difference between original and this JSON
- Throws:
InvalidDataException- if the original or this instance is invalid
-
apply
Apply a binary delta to this JSON value to create a new value.Convenient equivalent to
Diffusion.dataTypes().json().binaryDeltaType().apply(this, delta).- Throws:
InvalidDataException- if this instance or delta is invalid
-
diff
Compare this JSON value with an earlier version to calculate a structural delta.Unlike a
binary delta, a structural delta can be queried to determine its effect.- Parameters:
original- the original JSON value to compare with this value- Returns:
- a structural delta representing the difference between original and this JSON
- Throws:
InvalidDataException- if original or this instance is invalid
-
validate
Check whether this instance is valid.Convenient equivalent to
Diffusion.dataTypes().json().validate(this).- Returns:
- This instance to allow fluent chaining. For example:
JSON json = jsonDataType.read(data).validate()
- Throws:
InvalidDataException- if this value is invalid
-
toJsonString
- Returns:
- JSON format string
- Throws:
InvalidDataException- if the underlying CBOR data is not valid; for example, if it contains an invalid CBOR sequence, no data, or more that one CBOR data item
-