2015-05-06 17 views
6

Ho trovato molte domande simili ma nessuna di queste ha aiutato.Problema di token di tipo Gson con deserializzazione generica

Questo funziona:

public class Assets<T> { 

public T getAndDeserializeAsset(String endpoint, String assetId, Client client){ 
    Response response = client.get(endpoint+assetId); 
    Gson gson = new Gson(); 
    T asset = gson.fromJson(response.body, new TypeToken<Email>(){}.getType()); 
    return asset; 
} 

}

Questo non lo fa:

public class Assets<T> { 

public T getAndDeserializeAsset(String endpoint, String assetId, Client client){ 
    Response response = client.get(endpoint+assetId); 
    Gson gson = new Gson(); 
    T asset = gson.fromJson(response.body, new TypeToken<T>(){}.getType()); 
    return asset; 
} 

}

l'ho fatto in base alla documentazione ufficiale, quindi non ho idea perché non funziona

Errore:

Exception in thread "main" java.lang.ClassCastException: com.rest.api.Response cannot be cast to model.Email 
at main.Main.main(Main.java:34) 

risposta

0

L'unica cosa che ha senso è che l'istanza di Assets<T> deve essere un'istanza di Assets<Response>, non di Assets<Email>. Sei assolutamente sicuro che la tua istanza di Assets sia del tipo corretto?

Inoltre, ricordare che Gson non è covariante; quando si specifica il tipo utilizzando TypeToken, è necessario utilizzare il tipo esatto che si desidera deserializzare. Ad esempio, se si utilizza la definizione della classe:

class Email extends Response { 

e quindi utilizzare:

new Assets<Response>(); 

Perché GSON non è covariante, non ha modo di sapere che cosa si vuole veramente è un Email.

0

Il codice precedente non interpreta il valore come tipo, poiché Gson richiama Assets.getClass() per ottenere le informazioni sulla classe, ma questo metodo restituisce una classe non elaborata, Assets.class. Ciò significa che Gson non ha modo di sapere che si tratta di un oggetto di tipo Attività <, e non solo risorse semplici.

È possibile risolvere questo problema specificando il tipo parametrico corretto per il tipo generico. Puoi farlo usando la classe TypeToken.

Type AssetsType = new TypeToken<Assets<Example>>() {}.getType(); 
gson.toJson(assets, AssetsType); 
gson.fromJson(json, AssetsType); 

Per ulteriori informazioni, controllare gson-user-guide

Problemi correlati