Reputation: 219
I have a concrete class called "Clerk" that implements an interface called "Worker". I want to deserialize my Clerk object and store it into a Worker object, just like we can normally do if I had this:
Worker clerkWorker = new Clerk("abc", "alice white");
Only instead I have the clerk json that I want to deserialize and store into clerkWorker:
{
"uid": "1a-2wq"
"name": "Maryanne Chen"
}
The interface:
public interface Worker {
int getUID();
String getName();
void work();
}
The class implementing it:
private class Clerk implements Worker {
int uid;
String name;
public Clerk(id, fullname) {
uid = id;
name = fullname;
}
public void work() {
System.out.println("Clerk is processing files");
}
}
Following the second solution described here: Using Gson with Interface Types I copied RuntimeTypeAdapterFactory locally to use it:
RuntimeTypeAdapterFactory typeFactory =
RuntimeTypeAdapterFactory.of(Worker.class, "type");
typeFactory.registerSubtype(Clerk.class);
Gson gson = new GsonBuilder().registerTypeAdapterFactory(typeFactory).create();
final Reader r = getReader(jsonFile);
return gson.fromJson(r, typeToken.getType());
I've verified my getReader function is working. I get an exception:
"cannot deserialize interface Worker because it does not define a field named type".
Upvotes: 0
Views: 692
Reputation: 1303
If Clerk
is a Worker
, then there shouldn't be any reason you can't just do exactly what you already showed with the constructor example.
Worker w = (new Gson()).fromJson( jsonData, Clerk.class ) ;
I'm not sure why you'd want so much to cast upward like this right away, since anything that wants a Worker
should be able to take the Clerk
directly...
Upvotes: 1
Reputation: 5087
When you tell Gson to deserialize something with an interface type, it has to somehow figure out which implementing class it should use. It does this by checking a special field in the json data. When you call RuntimeTypeAdapterFactory.of(Worker.class, "type");
, you are telling Gson that the field it should check to figure out which class it should use is named "type". When you then give it a chunk of json data that doesn't have that field, it complains.
To fix this, you will need to either add the "type" field to your json data, or tell Gson in the code to deserialize as Clerk
, not Worker
.
Upvotes: 1