在Java中反序列化对象中的通用对象

时间:2017-01-13 14:26:08

标签: java android json gson

我有一个名为WebApiReturn的类,它是以Json的形式发送给我的类的表示形式:

 public class WebApiReturn<T> {
    @SerializedName("objectReturn")
    public T ObjectReturn;
    @SerializedName("hasError")
    public boolean HasError;
    @SerializedName("errorMessage")
    public String ErrorMessage;
    @SerializedName("errorCode")
    public String ErrorCode;
}

除此之外,我还有一个我想从WebService获取的表示类:

public class MyObject {
    public int ID_Obj;
    public String ObjectName;
    public Date LastLoginDate;
}

一个名为getObject的函数,它获取由我的WebService发送的格式为Json的String,并将其转换为此Java类:

public Object getObject(Class wantedResponseClass) throws JSONException{
        Gson gson = new Gson();
        object = gson.fromJson(this.result, wantedResponseClass);

        return object;
    }

我的Json String就是:

{"objectReturn":{"iD_Obj":123,"objectName":"TestName","lastLoginDate":"0001-01-01T00:00:00"},"hasError":false,"errorMessage":null,"errorCode":null}

在我的代码中和我的代码中,我尝试得到我的对象:

WebApiReturn<MyObject> responseFromServer = new WebApiReturn<>();
try {
     responseFromServer =(WebApiReturn<MyObject>) getObject(responseFromServer.getClass());
     } catch (Exception e) {
          e.printStackTrace();
     }

但是当我声明WebApiReturn<MyObject> responseFromServer = new WebApiReturn<>();时,应该转向MyObject的泛型T ObjectReturn没有从Json中填充它的表示。有人知道我现在做错了什么吗?我应该使用其他类型的反序列化还是类似的东西?

2 个答案:

答案 0 :(得分:0)

您不能使用泛型类型,在T的运行时实例被Object替换,因此您尝试将其反序列化为Object而不是MyObject }。

如果您将T替换为MyObject,那么它至少可以用于您的示例。但是,我想你使用的是通用类型,因为ObjectReturn可以有多种类型......你可能会在这里找到答案Gson deserialize JSON array with multiple object types

答案 1 :(得分:0)

为了在反序列化器中有一个带有泛型类的类,我创建了一个带有T实例的类,它扩展了AsyncTask(从服务器获取Json异步的UI线程)并使用了JSONObject AND Gson Library将我的课分为两部分:类本身和泛型内部。然后我返回2 Elements。

这是我的班级:

public class RestClient<t>  extends AsyncTask<String, String, String> {

private Class<t> tClass;

private t returnGenericObject;
private WebApiReturn webApiReturn;

private AsyncCallback callback;

public RestClient(Class<t> tClass)
{
    //The instance of the class you want
    this.tClass = tClass;
    webApiReturn= new WebApiReturn();
}

//You get the WebApiReturn with this method
public WebApiReturn getWebApiReturn(){
    return webApiReturn;
}

//You get the inside generic object with this method
public Object getObjectResponse(){
    return returnGenericObject;
}


@Override
protected String doInBackground(String... OnlyTheURL) {
    String urlString = OnlyTheURL[0];
    try {
        URL url = new URL(urlString);

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");

        connection.connect();

        String result = convertStreamToString(connection.getInputStream()); //A function to convert Stream to String...

        connection.disconnect();

        //Created a JSONObject from the result of the connection
        JSONObject jsonObject = new JSONObject(result);

        //Don't set the Generic Object because it will crash when you try to get back
        webApiReturn.setHasError(jsonObject.getBoolean("hasError"));
        webApiReturn.setErrorMessage (jsonObject.getString("errorMessage"));
        webApiReturn.setErrorCode(jsonObject.getString("errorCode"));

        //Get the String of the generic object within the WebApiReturn
        String obj = jsonObject.get("objetoRetorno").toString();
        //With Gson convert it to the class you expect (that you instanciated in the constructor)
        Gson gson = new Gson();
        ObjetoDeRetorno = gson.fromJson(obj, tClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

并且您想要调用它的地方就是这样:

RestClient<YourObject> restClient = new RestClient<>(YourObject.class);
restClient.execute();
Thread.sleep(5000); //You can do this other better ways, but just as example I'm doing this...

//After the execution you get your objects:
WebApiReturn return = getWebApiReturn();
YourObject object = (YourObject) restClient.getObjectResponse();