I have added a BooleanProperty into a DAO class which is to be serializes into JSON and send across to a server to be saved in a MySQL database. The reason I am using the BooleanProperty is because I want to use data binding for the 'isActive' field in my JavaFX desktop application.
The class to be serialized:
package com.example.myapplication
import lombok.Data;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
@Data
public class MyDAO {
private int id;
private String firstName;
private String lastname;
private final BooleanProperty isActive = new SimpleBooleanProperty();
}
I am serializing to JSON using Gson:
StringEntity entity = new StringEntity(new Gson().toJson(myDTO), "UTF-8");
When this gets serialized to JSON, it looks like this:
{
"id":0,
"first_name":"Joe",
"last_name":"Bloggs",
"is_active":{
"name":"",
"value":false,
"valid":true
}
}
This is causing problems on the server when deserializing (using Jackson), as the server expects a boolean value to correspond with what will be saved in the database. Is there a way to just get the true/false value deserialized from the BooleanProperty?
This is what I would like to see in the server:
{
"id":0,
"first_name":"Joe",
"last_name":"Bloggs",
"is_active": false,
}
Your client app uses Gson
to serialise POJO
to JSON
and server app uses Jackson
to deserialise JSON
back to POJO
. In both cases these two libraries by default serialise provided classes as regular POJO
-s. In your POJO
you use JavaFX Properties
which are wrappers for values with extra functionality. When you serialise POJO
to JSON
sometimes you need to hide internal implementation of POJO
and this is why you should implement custom serialiser or use FX Gson library.
1. Custom serialiser
To write custom serialiser you need to implement com.google.gson.JsonSerializer
interface. Below you can find an example hot it could look like:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import lombok.Data;
import java.lang.reflect.Type;
public class GsonApp {
public static void main(String[] args) {
MyDAO myDAO = new MyDAO();
myDAO.setId(1);
myDAO.setFirstName("Vika");
myDAO.setLastname("Zet");
myDAO.getIsActive().set(true);
Gson gson = new GsonBuilder()
.registerTypeAdapter(BooleanProperty.class, new BooleanPropertySerializer())
.setPrettyPrinting().create();
System.out.println(gson.toJson(myDAO));
}
}
class BooleanPropertySerializer implements JsonSerializer<BooleanProperty> {
@Override
public JsonElement serialize(BooleanProperty src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.getValue());
}
}
@Data
class MyDAO {
private int id;
private String firstName;
private String lastname;
private final BooleanProperty isActive = new SimpleBooleanProperty();
}
Above code prints:
{
"id": 1,
"firstName": "Vika",
"lastname": "Zet",
"isActive": true
}
2. FX Gson
In case you use many types from javafx.beans.property.*
package good idea would be to use FX Gson
library which implement custom serialisers for most used types. You just need to add one extra dependency to your Maven
POM
file:
<dependency>
<groupId>org.hildan.fxgson</groupId>
<artifactId>fx-gson</artifactId>
<version>3.1.2</version>
</dependency>
Example usage:
import com.google.gson.Gson;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import lombok.Data;
import org.hildan.fxgson.FxGson;
public class GsonApp {
public static void main(String[] args) {
MyDAO myDAO = new MyDAO();
myDAO.setId(1);
myDAO.setFirstName("Vika");
myDAO.setLastname("Zet");
myDAO.getIsActive().set(true);
Gson gson = FxGson.coreBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(myDAO));
}
}
Above code prints:
{
"id": 1,
"firstName": "Vika",
"lastname": "Zet",
"isActive": true
}