I have a main class MainDataObject in which I am loading the json.
public class MainDataObject {
private Class<?> jobClass;
private int time;
private String tables;
public MainDataObject(String jobClassname){
jobClass = (Class<?>)Class.forName(jobClassname);
}
In json, jobClass is a string, but I need to load it as a Class object. I have tried writing custom Deserializer, but it didn't work.
public class ClassDeserializer implements JsonDeserializer<MainDataObject> {
@Override
public MainDataObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
String jobClassName = json.getAsJsonObject().get("jobClass").getAsString();
MainDataObject mdo = new MainDataObject(jobClassName);
return mdo;
}
}
And I parse json into MainDataObject like:
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(jobsConfigPath));
} catch (JsonSyntaxException | JsonIOException | FileNotFoundException e1) {
LOGGER.error("Exception"+ e1 +"encountered while parsing "+jobsConfigPath);
throw new RuntimeException("Exception"+ e1 +"encountered while parsing "+jobsConfigPath);
}
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = new Gson();
gsonBuilder.registerTypeAdapter(MainDataObject.class, new ClassDeserializer()).create();
MainDataObject jobList = gson.fromJson(br, MainDataObject.class);
I am not able to parse jobClass into Class object.
You have three mistakes in your code that I can see
MainDataObject
..
import com.google.gson.*;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.junit.Test;
import java.lang.reflect.Type;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
public class MeTest {
@Test
public void test() {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.registerTypeAdapter(MainDataObject.class, new ClassDeserializer())
.create();
String json = "{\"jobClass\":\"java.util.AbstractCollection\",\"time\":100,\"tables\":\"tables\"}";
MainDataObject data = new MainDataObject("java.util.AbstractCollection");
data.time = 100;
data.tables = "tables";
MainDataObject jobList = gson.fromJson(json, MainDataObject.class);
assertThat(jobList, is(data));
}
}
class ClassDeserializer implements JsonDeserializer<MainDataObject> {
@Override
public MainDataObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
String jobClassName = json.getAsJsonObject().get("jobClass").getAsString();
MainDataObject mdo = new MainDataObject(jobClassName);
mdo.tables = json.getAsJsonObject().get("tables").getAsString();
mdo.time = json.getAsJsonObject().get("time").getAsInt();
return mdo;
}
}
// Lombok
@EqualsAndHashCode @ToString
class MainDataObject {
Class<?> jobClass;
int time;
String tables;
public MainDataObject(String jobClassname){
try {
jobClass = (Class<?>)Class.forName(jobClassname);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
However a better option may be to write a deserializer for the Class type.
class ClassDeserializer implements JsonDeserializer<Class> {
@Override
public Class deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
String jobClassName = json.getAsString();
try {
return Class.forName(jobClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}