使用 Gson 通过参数化构造函数将 Json 加载到 java class
Using Gson to load Json into java class with parameterised constructor
我有一个主 class MainDataObject,我正在其中加载 json。
public class MainDataObject {
private Class<?> jobClass;
private int time;
private String tables;
public MainDataObject(String jobClassname){
jobClass = (Class<?>)Class.forName(jobClassname);
}
在json中,jobClass是一个字符串,但我需要将它加载为一个Class对象。我曾尝试编写自定义反序列化器,但没有成功。
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;
}
}
然后我将 json 解析为 MainDataObject,如:
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);
我无法将作业Class 解析为Class 对象。
你是什么意思:
我无法完成工作Class = (Class)Class.forName(工作Class姓名);在 Class 作业 Class 的 MainDataObject 的构造函数中。
我试过了。它想 用 try catch 块包围或添加 throws 声明。
我看到你的代码中有 3 个错误
- 您正在创建一个 GsonBuilder 但从未使用过它。
- 你只是设置了'jobClassName'而不是
MainDataObject
的所有元素。
- 构造函数需要 try/catch 或抛出异常。
.
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();
}
}
}
然而,更好的选择可能是为 Class 类型编写反序列化器。
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;
}
}
}
我有一个主 class MainDataObject,我正在其中加载 json。
public class MainDataObject {
private Class<?> jobClass;
private int time;
private String tables;
public MainDataObject(String jobClassname){
jobClass = (Class<?>)Class.forName(jobClassname);
}
在json中,jobClass是一个字符串,但我需要将它加载为一个Class对象。我曾尝试编写自定义反序列化器,但没有成功。
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;
}
}
然后我将 json 解析为 MainDataObject,如:
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);
我无法将作业Class 解析为Class 对象。
你是什么意思:
我无法完成工作Class = (Class)Class.forName(工作Class姓名);在 Class 作业 Class 的 MainDataObject 的构造函数中。
我试过了。它想 用 try catch 块包围或添加 throws 声明。
我看到你的代码中有 3 个错误
- 您正在创建一个 GsonBuilder 但从未使用过它。
- 你只是设置了'jobClassName'而不是
MainDataObject
的所有元素。 - 构造函数需要 try/catch 或抛出异常。
.
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();
}
}
}
然而,更好的选择可能是为 Class 类型编写反序列化器。
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;
}
}
}