public interface JSON extends 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.
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.
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); }
The mapping from a JSON string to and from CBOR-format binary data is mostly straightforward, but there are a few limitations. In particular:
0.3
as
text. The default JSONDataType.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.
Modifier and Type | Method and Description |
---|---|
JSON |
apply(BinaryDelta delta)
Apply a binary delta to this JSON value to create a new value.
|
BinaryDelta |
binaryDiff(JSON original)
Compare this JSON value with an earlier version to create a binary delta.
|
JSONDelta |
diff(JSON original)
Compare this JSON value with an earlier version to calculate a structural
delta.
|
String |
toJsonString() |
JSON |
validate()
Check whether this instance is valid.
|
asInputStream, copyTo, length, toByteArray
BinaryDelta binaryDiff(JSON original) throws InvalidDataException
Convenient equivalent to
Diffusion.dataTypes().json().binaryDeltaType().diff(original, this)
.
InvalidDataException
- if the original or this instance is invalidJSON apply(BinaryDelta delta) throws InvalidDataException
Convenient equivalent to
Diffusion.dataTypes().json().binaryDeltaType().apply(this, delta)
.
InvalidDataException
- if this instance or delta is invalidJSONDelta diff(JSON original) throws InvalidDataException
Unlike a binary delta
, a structural delta can
be queried to determine its effect.
original
- the original JSON value to compare with this valueInvalidDataException
- if original or this instance is invalidJSON validate() throws InvalidDataException
Convenient equivalent to Diffusion.dataTypes().json().validate(this)
.
JSON json = jsonDataType.read(data).validate()
InvalidDataException
- if this value is invalidString toJsonString() throws InvalidDataException
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 itemCopyright © 2022 Push Technology Ltd. All Rights Reserved.