使用Gson将Json加载到带有参数化构造函数的java类中

时间:2015-10-30 09:35:50

标签: java json gson json-deserialization

我有一个主类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);

我无法将jobClass解析为Class对象。

2 个答案:

答案 0 :(得分:0)

你是什么意思:

我无法做jobClass =(Class)Class.forName(jobClassname);在MainDataObject for Class jobClass的构造函数中。

我试过了。它希望环绕try catch块或添加throws声明。

答案 1 :(得分:0)

您可以在代码中看到三个错误

  • 您正在创建一个GsonBuilder但从未使用它。
  • 您只需设置&#39; jobClassName&#39;并非MainDataObject
  • 的所有元素
  • ctor需要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 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;
        }
    }
}