2017-01-13 2 views
3

J'ai une classe appelée WebApiReturn qui est la représentation d'une classe qui m'a envoyé comme JSON:Désérialise un objet générique dans un objet en Java

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

plus que je la classe de représentation de celle Je suis en train de faire de mon WebService:

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

et une fonction appelée getObject qui obtiennent une chaîne formatée JSON envoyée par mon WebService et le convertir en cette classe Java:

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

     return object; 
    } 

Et mon JSON cordes est, par exemple:

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

Dans et dans mon code, je tente d'obtenir mon objet comme:

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

Mais le T ObjectReturn générique, qui devrait être tourné à un MyObject quand j'ai déclaré WebApiReturn<MyObject> responseFromServer = new WebApiReturn<>(); n'est pas rempli avec la représentation de la Json. Quelqu'un sait ce que je fais mal en ce moment? Dois-je utiliser un autre type de désérialisation ou quelque chose comme ça?

Répondre

1

Pour avoir une classe avec une classe générique dans le deserializer, j'ai créé une classe avec une instance de T cela étend AsyncTask (pour obtenir le Json du serveur asynchrone du thread UI) et utilisé JSONObject et Gson Library pour diviser ma classe en 2 parties: la classe elle-même et le générique à l'intérieur. Puis je reviens alors comme 2 éléments.

Voici ma classe:

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

et où vous voulez l'appeler vous faire comme ceci:

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

Vous ne pouvez pas utiliser un type générique, à des instances d'exécution de T obtenir remplacé par Object donc par conséquent, vous essayez de désérialisé dans un Object plutôt que dans MyObject.

Si vous avez remplacé T par MyObject cela fonctionnerait, pour votre exemple au moins. Cependant, j'imagine que vous utilisez un type générique parce que ObjectReturn peut avoir plusieurs types ... vous pouvez obtenir une réponse ici Gson deserialize JSON array with multiple object types