|
|
This page contains the user-documentation for the [**Json**](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/commons/-/blob/master/src/main/java/de/rwth/montisim/commons/utils/json/Json.java) class.
|
|
|
|
|
|
This class can be used to serialize and de-serialize objects to and from JSON. It also reads different *Java Annotations* that can be added to the serialized class or its field in order to customize the serialization. Classes can also implement the `CustomJson` interface in order to perform non-standard serialization. This serializer also supports a simple type system in order to handle different sub-classes.
|
|
|
|
|
|
[[_TOC_]]
|
|
|
|
|
|
# Interface
|
|
|
|
|
|
## Serialization (`toJson()`)
|
|
|
|
|
|
The function to serialize any Java Object is:
|
|
|
```java
|
|
|
String json = Json.toJson(anyObject);
|
|
|
```
|
|
|
|
|
|
If you want to use an existing `JsonWriter`, use:
|
|
|
```java
|
|
|
JsonWriter w = ...;
|
|
|
Json.toJson(w, anyObject, null);
|
|
|
```
|
|
|
|
|
|
## De-serialization
|
|
|
|
|
|
There are two ways to de-serialize JSON objects. Through **instantiation** or by **reading** the JSON to an existing object.
|
|
|
|
|
|
### Instantiation (`instantiateFromJson()`)
|
|
|
|
|
|
To create an object from JSON for some `ObjectType`, you must specify the desired class as follows:
|
|
|
```java
|
|
|
ObjectType object = Json.instantiateFromJson(jsonString, ObjectType.class);
|
|
|
// Or using a 'File' object:
|
|
|
ObjectType object = Json.instantiateFromJson(jsonFile, ObjectType.class);
|
|
|
```
|
|
|
|
|
|
The instantiation can also be performed using an existing `JsonTraverser`:
|
|
|
```java
|
|
|
JsonTraverser traverser = ...;
|
|
|
ObjectType object = Json.instantiateFromJson(traverser, ObjectType.class, null);
|
|
|
```
|
|
|
|
|
|
The instantiation doesn't work directly on *generic classes*, but generic classes as fields of serialized objects are supported. (Example: a class containing a Vector<...> field can be instantiated.)
|
|
|
|
|
|
### Reading (`fromJson()`)
|
|
|
|
|
|
For existing (non-null) objects, JSON containing **partial** data can be read and will override the specified fields. This is called using:
|
|
|
```java
|
|
|
ObjectType object = ...;
|
|
|
Json.fromJson(jsonString, object);
|
|
|
```
|
|
|
|
|
|
This can also be done using an existing `JsonTraverser`:
|
|
|
```java
|
|
|
JsonTraverser traverser = ...;
|
|
|
ObjectType object = ...;
|
|
|
Json.fromJson(traverser, object, null);
|
|
|
```
|
|
|
|
|
|
### Reading example
|
|
|
|
|
|
For the class:
|
|
|
```java
|
|
|
class Foo {
|
|
|
int f1;
|
|
|
String f2;
|
|
|
String f3;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
And the following JSON string:
|
|
|
```json
|
|
|
{
|
|
|
"f1": 1,
|
|
|
"f3": "alternative string"
|
|
|
}
|
|
|
```
|
|
|
|
|
|
This code
|
|
|
```java
|
|
|
Foo foo = new Foo();
|
|
|
foo.f1 = 4;
|
|
|
foo.f2 = "string a";
|
|
|
foo.f3 = "string b";
|
|
|
// ...
|
|
|
Json.fromJson(inputString, foo);
|
|
|
```
|
|
|
will change the `f1` and `f3` entries of the `foo` object.
|
|
|
|
|
|
# Type system
|
|
|
|
|
|
This serializer does not export the types of the classes it serializes. This means it has to be used on data-structures where the types are well defined. As with the `instantiateFromJson()` call that requires an explicit class type.
|
|
|
De-serializing JSON that doesn't match the specified type will cause 'unexpected ...' errors since the JSON entries won't match the expected ones.
|
|
|
|
|
|
Data-structures that contain polymorphic fields (that can contain objects with different sub-types) can be made de-serializable by adding the `@Typed` annotation to all the sub-classes. This will add a `"type"="..."` entry at the start of the serialized objects and allows the correct instantiation when de-serializing.
|
|
|
|
|
|
## Registering the sub-types
|
|
|
|
|
|
Make sure that all the possible sub-types are registered by the `Json` class by calling
|
|
|
```java
|
|
|
Json.registerType(ObjectType.class);
|
|
|
```
|
|
|
at some point before calling `instantiateFromJson()` with sub-typed fields.
|
|
|
|
|
|
> **Notes**:
|
|
|
> - Code in `static {}` blocks will only be executed the first time a class is used.
|
|
|
> - The manual registration might be replaced by dependency injection at some point.
|
|
|
|
|
|
# Customization
|
|
|
|
|
|
The serialized output can be made user-friendly, for example for use as configuration, by customizing exactly how the output looks like.
|
|
|
|
|
|
## Defaults
|
|
|
|
|
|
These are the defaults when serializing:
|
|
|
- All fields (even the private ones) are serialized. To exclude a field, add the `transient` keyword.
|
|
|
- The fields have their name as key in JSON objects.
|
|
|
- For `@Typed` classes, the type name is the class' name.
|
|
|
|
|
|
## Changing the defaults
|
|
|
|
|
|
To manually specify which fields must be serialized (inclusion vs exclusion by default), the `@FieldSelect(Select.EXPLICIT)` annotation can be added to a class. Then, only the fields with the `@JsonEntry` annotation will be serialized.
|
|
|
|
|
|
To change the name used as key for fields, add the `@JsonEntry("otherKeyName")` annotation with the alternative name.
|
|
|
|
|
|
To change the type name for sub-classes, add the alternative name as parameter of the annotation: `@Typed("alternative type name")`.
|
|
|
|
|
|
## Custom serialization
|
|
|
|
|
|
> TODO
|
|
|
|
|
|
By implementing the `CustomJson` interface, classes can manually write and parse their content using the `JsonWriter` and `JsonTraverser`. |
|
|
\ No newline at end of file |