Here is some legal stuff. What I will present now could be not be included in the final version of the product. So the text basically says that you shouldn't trust me. Trust no one.
I will start with defining and explaining what JSON-B is.
After that we will go through JSR status and progress.
Next I will show you what is in the spec.
Why do we need a standard?
Native JSON Binding frameworks
Not comparing with JAXB inspired frameworks
Goal of standardizing.
Experts group
OK. Now lets talk about the specification.
Current state – Early Draft
Now it’s time to see what’s in the spec. We will start with default mapping.
The first question comes is what is default mapping?
JSONB engine with default mapping sample
We go though all these items later
What is JSON-B engine?
Lets take a look how default mapping works. Here is a list of all basic types handled by JSON-B specification. It includes all basic types and the corresponding primitives.
The rules are simple: toString() method is used for serialization and the corresponding parse() method for deserialization.
Here is a sample. All frameworks handle it the same way, so no comparison here.
Specific types. The specific types are JDK types specified in JSON-B spec which are not basic. It includes…
For Big and URL types toString() method is used for serialization the same as for basic types. For deserialization (here comes the difference) default constructor with String argument is used.
Optional types were introduced in Java 8. Optional can be empty or contains a value. If it does have a value it gets represented by it. The value is processed instead of Optional type. If it’s empty it’s precessed as null.
Not all frameworks handle optional types the same way.
Calendar with no time
Calendar with no time portion.
Now lets talk about classes. The specification strictly defines what kind of classes are supported.
Specification is also clear about what types of fields are supported and in which order fields are serialized.
Arrays and Collections. Here is a list of officially supported types. Sample is on the right side. Nothing much to say here. Just important to mention that null elements are not skipped here as in case of class fields and always serialized.
JSON-P types. JSON-P is used by JSON-B as a parser. The following JSON-P types are supported.
The rules are simple. JsonWriter from jsonp is used for serialization and JsonReader for deserialization.
Here is a sample. As you see, JSON-P class is serialized as a normal Java class.
There are Genson and Jackson modules to support JSON-P types. Gson doesn’t have a special JSONP types support. But it can be added by creating a custom serializer there.
This is it about defaults. Now lets talk about how mapping can be customized.
There are 2 types of configuration: Compile type and Runtime.
JsonbBuilder.withProvider()
On this slide a summarized all customizations provided by JSONB. Other frameworks do have it as well. Some them offer much more complicated customizations. Lets quickly go throw these customizations in details.
Sometimes we need to have a field name in JSON document different than in Java class. This is a common use case. JSONB offers JsonbProperty annotation to do it. Other frameworks have it the similar way but annotation is named differently.
Here is a sample. We have a Customer class which serializes to this JSON document by default. We want to serialize firstName field as name.
In order to do it we put JsonbProperty on firstName field with different name specified. Alternatively JsonbProperty annotation can be placed on a getter.
We actually can use different property names for serialization and for deserialization as this sample shows. Strange use case, is it?
Property naming strategy is a way to change property names globally. By default field is serialized with a name as it is defined in a class. If this is not a desired behavior JSONB supports 6 predefined strategies or a custom one can be created. Naming strategy is specified at runtime using withPropertyNamingStrategy of JsonbConfig class.
All other frameworks have a similar feature.
ANY - performance
Here is how other frameworks handle ignoring properties.
Different frameworks handle nulls different way. Here is a comparison table.
Sometimes we need to customize a way how class instance is created. For example if class is created by a static factory method instead of a default constructor. In this case this method has to be annotated with JsonbCreator annotation and it will be called to make an instance of a class instead of a default constructor. Parameters are also supported. Take a look at the sample. Order class has a field customer. Customer class has a method annotated with JsonbCreator annotation. During unmarshalling this method is called and ‘two’ is passed as a parameter.
Tokenizers, Readers
All other frameworks have similar features. All of them allow you to define classes with custom logic used to control binding process. Genson actually supports JAXB annotations in JAXBBundle. Jackson has a very powerfull and simple mix-ins mechanism.
Again. All other frameworks have a similar feature.
If binary data is processed it has to be encoded. JSONB supports 3 types of binary encoding: byte, base_64 and base_64_url. Encoding is specified as part of runtime configuration using withBinaryDataStrategy method of JsonbConfig class.
I-JSON (”Internet JSON”) is a restricted profile of JSON. It’s a standard draft.
JSON-B fully supports I-JSON by default with three exceptions:
It is possible to switch a full support mode in runtime config using withStrictIJSONSerializationCompliance method of JsonbConfig class.
This is it about defaults. Now lets talk about how mapping can be customized.
Deserializer doesn’t know the root type, so it must be passed
In case of generic type variables, an extension or anonymous class must be passed to Jsonb.
Considering using TypeToken which is popular in other frameworks.
If generic variable type cannot be resolved it is treated as Object – HashMap is used to populate it.
Interface and abstract types cannot be resolved by default. (with exception to known interfaces like Map/List).
Supposed to be created per “class model” or configuration.
JSONP Generator/Parser instances created and closed inside JSONB each toJson / fromJson call
Deserializer doesn’t know the root type, so it must be passed
In case of generic type variables, an extension or anonymous class must be passed to Jsonb.
Considering using TypeToken which is popular in other frameworks.
If generic variable type cannot be resolved it is treated as Object – HashMap is used to populate it.
Interface and abstract types cannot be resolved by default. (with exception to known interfaces like Map/List).
Deserializer doesn’t know the root type, so it must be passed
In case of generic type variables, an extension or anonymous class must be passed to Jsonb.
Considering using TypeToken which is popular in other frameworks.
If generic variable type cannot be resolved it is treated as Object – HashMap is used to populate it.
Interface and abstract types cannot be resolved by default. (with exception to known interfaces like Map/List).
Deserializer doesn’t know the root type, so it must be passed
In case of generic type variables, an extension or anonymous class must be passed to Jsonb.
Considering using TypeToken which is popular in other frameworks.
If generic variable type cannot be resolved it is treated as Object – HashMap is used to populate it.
Interface and abstract types cannot be resolved by default. (with exception to known interfaces like Map/List).
Deserializer doesn’t know the root type, so it must be passed
In case of generic type variables, an extension or anonymous class must be passed to Jsonb.
Considering using TypeToken which is popular in other frameworks.
If generic variable type cannot be resolved it is treated as Object – HashMap is used to populate it.
Interface and abstract types cannot be resolved by default. (with exception to known interfaces like Map/List).
Deserializer doesn’t know the root type, so it must be passed
In case of generic type variables, an extension or anonymous class must be passed to Jsonb.
Considering using TypeToken which is popular in other frameworks.
If generic variable type cannot be resolved it is treated as Object – HashMap is used to populate it.
Interface and abstract types cannot be resolved by default. (with exception to known interfaces like Map/List).