-
Notifications
You must be signed in to change notification settings - Fork 55
Custom serializers and deserializers
First, create a class that extends com.github.nmorel.gwtjackson.client.JsonSerializer
if you want to create a serializer or com.github.nmorel.gwtjackson.client.JsonDeserializer
for a deserializer.
public class PersonJsonSerializer extends JsonSerializer<Person> { ... }
The parameter of JsonSerializer
and JsonDeserializer
is the type you want to (de)serialize.
Then implement your (de)serialization logic in the doSerialize or doDeserialize method.
@Override
public void doSerialize( JsonWriter writer, Person person, JsonSerializationContext ctx, JsonSerializerParameters params ) {
writer.value( person.getFirstname() + " " + person.getLastname() );
}
In order for the generator to instantiate your (de)serializer, you need a public constructor or, better, a public static method that returns a singleton instance.
private static final PersonSerializer INSTANCE = new PersonSerializer();
/**
* @return an instance of {@link PersonSerializer}
*/
public static PersonSerializer getInstance() {
return INSTANCE;
}
private PersonSerializer() { }
The generator first looks for a static method and default to constructor if it can't find one.
In the end, you should have something similar to :
public class PersonSerializer extends JsonSerializer<Person> {
private static final PersonSerializer INSTANCE = new PersonSerializer();
/**
* @return an instance of {@link PersonSerializer}
*/
public static PersonSerializer getInstance() {
return INSTANCE;
}
private PersonSerializer() { }
@Override
protected void doSerialize( JsonWriter writer, Person person, JsonSerializationContext ctx, JsonSerializerParameters params ) {
writer.value( person.getFirstname() + " " + person.getLastname() );
}
}
If the type you want to (de)serialize is a generic type like Optional, the (de)serializers for the generic's types will be passed to the constructor or static method of your (de)serializer. So you have to add them like OptionalJsonSerializer :
private final JsonSerializer<T> serializer;
/**
* @param serializer {@link JsonSerializer} used to serialize the object inside the {@link Optional}.
*/
private OptionalJsonSerializer( JsonSerializer<T> serializer ) {
if ( null == serializer ) {
throw new IllegalArgumentException( "serializer cannot be null" );
}
this.serializer = serializer;
}
For generic Object serialization and deserialization additional parameters need to be provided. For example the full specified class name of the generic object has to be stored.
@JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY, property="class")
public Object object;
Additionally a list of classes that are eligible for generic serialization/deserialization have to be whitelisted in the confuration:
@Override
protected void configure() {
whitelist("com.package.EligibleClass");
whitelist("com.package.wildcard.*");//wildcard matching works too
}
To register your (de)serializer, create a class that extends com.github.nmorel.gwtjackson.client.AbstractConfiguration
.
Then register your class in your *.gwt.xml file with the property gwtjackson.configuration.extension
:
<extend-configuration-property name="gwtjackson.configuration.extension" value="com.MyConfiguration" />
Inside the configure()
method, you can define serializer and/or deserializer for :
- primitive types :
primitiveType( boolean.class ).serializer( BooleanJsonSerializer.class ).deserializer( BooleanJsonDeserializer.class );
- types :
type( String.class ).serializer( StringJsonSerializer.class ).deserializer( StringJsonDeserializer.class );
- Map's key type :
key( UUID.class ).serializer( UUIDKeySerializer.class ).deserializer( UUIDKeyDeserializer.class );
You can look at the Guava extension for additional examples :