简体   繁体   English

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

[英]Deserialize a generic object within an object in Java

I have a class called WebApiReturn that is the representation of a class that is sent to me as Json: 我有一个称为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;
}

Besides that I have the representation class of the one I'm trying to get from my WebService: 除此之外,我还尝试从WebService获取的表示形式类:

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

And a function called getObject that get a String formatted as Json sent by my WebService and convert it into this Java Class: 还有一个名为getObject的函数,该函数获取由WebService发送的Json格式的String并将其转换为以下Java类:

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

        return object;
    }

And my Json String is, for example: 我的Json String例如:

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

In and in my code I try to get my object like: 在我的代码中,我尝试使我的对象像:

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

But then the generic T ObjectReturn, that should be turned to a MyObject when I declared WebApiReturn<MyObject> responseFromServer = new WebApiReturn<>(); 但是然后是通用的T ObjectReturn,当我声明WebApiReturn<MyObject> responseFromServer = new WebApiReturn<>();时,应将其转换为MyObject WebApiReturn<MyObject> responseFromServer = new WebApiReturn<>(); is not being filled with the representation of it from the Json. 没有被Json表示。 Someone know what am I doing wrong right now? 有人知道我现在做错了吗? Should I use another type of deserialization or something like that? 我是否应该使用其他类型的反序列化?

You can't use a generic type, at runtime instances of T get replaced with Object so therefore you are trying to deserialised into an Object instead of into MyObject . 您不能使用泛型类型,在运行时T实例将被Object替换,因此您尝试将其反序列化为Object而不是MyObject

If you replaced T with MyObject it would work, for your example at least. 如果将T替换为MyObject则至少可以使用该示例。 However, I imagine you are using generic type because ObjectReturn can have multiple type... you might get an answer here Gson deserialize JSON array with multiple object types 但是,我想您正在使用泛型类型,因为ObjectReturn可以有多种类型...您可能会在这里得到答案Gson将具有多种对象类型的JSON数组反序列化

To have a class with a generic class in it deserializer, I created a class with an instance of T that extends AsyncTask (to get the Json from the server asynchronous of the UI Thread) and used JSONObject AND Gson Library to split my class in 2 parts: the class itself and the generic inside. 为了在反序列化器中具有一个带有通用类的类,我创建了一个带有T实例的类,该实例扩展了AsyncTask(从UI线程的服务器异步获取Json),并使用JSONObject Gson库将我的类分为2个类。部分:类本身和内部的泛型。 Then I return then as 2 Elements. 然后我返回2个元素。

Here is my class: 这是我的课:

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

and where you want to call it you just do like this: 而您想调用它的地方就是这样:

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM