使用 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;
        }
    }
}