public class UserAction {
private final UUID uuid;
private String userId;
/* more fields, setters and getters here */
public UserAction(){
this.uuid = UUID.fromString(new com.eaio.uuid.UUID().toString());
}
public UserAction(UUID uuid){
this.uuid = uuid;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final UserAction other = (UserAction) obj;
if (this.uuid != other.uuid && (this.uuid == null || !this.uuid.equals(other.uuid))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 53 * hash + (this.uuid != null ? this.uuid.hashCode() : 0);
return hash;
}
}
I am using Gson to serilize and deserialize this class. As today I had to add a final UUID in this object. I have no problem serializing. I need to force gson to use public UserAction(UUID uuid)
constructor when deserializing. How can I achieve that ?
Gson requires the class to have a default no-args constructor.
3. Deserialize JSON With Extra Unknown Fields to Object. As you can see, Gson will ignore the unknown fields and simply match the fields that it's able to.
Deserialization – Read JSON using Gson. Deserialization in the context of Gson means converting a JSON string to an equivalent Java object. In order to do the deserialization, we need a Gson object and call the function fromJson() and pass two parameters i.e. JSON string and expected java type after parsing is finished ...
Introduction. Gson is the main actor class of Google Gson library. It provides functionalities to convert Java objects to matching JSON constructs and vice versa. Gson is first constructed using GsonBuilder and then toJson(Object) or fromJson(String, Class) methods are used to read/write JSON constructs.
You could implement a custom JsonDeserializer and register it with GSON.
class UserActionDeserializer implements JsonDeserializer<UserAction> {
public UserAction deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
return new UserAction(UUID.fromString(json.getAsString());
}
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(UserAction.class, new UserActionDeserializer());
Bear in mind that this code has not been tested.
Another approach to solve this problem would be to take advantage of the fact that during deserialization Gson will clobber any values set by constructors with new values found in the JSON, and so just use an InstanceCreator, which exists specifically "to create instances of a class that does not define a no-args constructor." This approach works especially well when the constructor to be used just assigns parameter values to fields, and doesn't perform any validity checks or otherwise perform any meaningful state-based processing.
Also, this approach does not require further custom deserialization -- no custom implementation of JsonDeserializer
is necessary. This can be advantageous to situations where introducing a custom deserializer to solve one small issue then necessitates "manual" processing of other JSON elements in close proximity, which could be non-trivial.
With that said, here's such a working solution that uses the preferred UserAction
constructor, but passes it only a null reference. The actual value from the JSON is later set. (Gson doesn't care that the uuid
field is supposed to be final.)
import java.lang.reflect.Type;
import java.util.UUID;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
public class Foo
{
public static void main(String[] args)
{
UserAction action = new UserAction(UUID.randomUUID());
action.setUserId("user1");
String json = new Gson().toJson(action);
System.out.println(json);
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(UserAction.class, new UserActionInstanceCreator());
Gson gson = gsonBuilder.create();
UserAction actionCopy = gson.fromJson(json, UserAction.class);
System.out.println(gson.toJson(actionCopy));
}
}
class UserActionInstanceCreator implements InstanceCreator<UserAction>
{
@Override
public UserAction createInstance(Type type)
{
return new UserAction(null);
}
}
class UserAction
{
private final UUID uuid;
private String userId;
public UserAction()
{
throw new RuntimeException("this constructor is not used");
}
public UserAction(UUID uuid)
{
this.uuid = uuid;
}
void setUserId(String userId)
{
this.userId = userId;
}
}
gson.registerTypeAdapter(DateTime.class, new DateTimeDeserializer());
private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return new DateTime(json.getAsJsonPrimitive().getAsString());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With