Gson TypeToken with dynamic ArrayList item type

Viewed 120679

I have this code:

Type typeOfObjectsList = new TypeToken<ArrayList<myClass>>() {}.getType();
List<myClass> objectsList = new Gson().fromJson(json, typeOfObjectsList);

It converts a JSON string to a List of objects. But now I want to have this ArrayList with a dynamic type (not just myClass), defined at runtime.

The ArrayList's item type will be defined with reflection.

I tried this:

    private <T> Type setModelAndGetCorrespondingList2(Class<T> type) {
        Type typeOfObjectsListNew = new TypeToken<ArrayList<T>>() {}.getType();
        return typeOfObjectsListNew;
    }

But it doesn't work. This is the exception:

java.sql.SQLException: Fail to convert to internal representation: {....my json....}
13 Answers

With kotlin you can use a below functions to converting (from/to) any (JsonArray/JsonObject) just in one line without need to send a TypeToken :-

Convert any class or array to JSON string

inline fun <reified T : Any> T?.json() = this?.let { Gson().toJson(this, T::class.java) }

Example to use :

 val list = listOf("1","2","3")
 val jsonArrayAsString = list.json() 
 //output : ["1","2","3"]

 val model= Foo(name = "example",email = "t@t.com") 
 val jsonObjectAsString = model.json()
//output : {"name" : "example", "email" : "t@t.com"}

Convert JSON string to any class or array

inline fun <reified T : Any> String?.fromJson(): T? = this?.let {
    val type = object : TypeToken<T>() {}.type
    Gson().fromJson(this, type)
}

Example to use :

 val jsonArrayAsString = "[\"1\",\"2\",\"3\"]"
 val list = jsonArrayAsString.fromJson<List<String>>()

 val jsonObjectAsString = "{ "name" : "example", "email" : "t@t.com"}"
 val model : Foo? = jsonObjectAsString.fromJson() 
 //or 
 val model = jsonObjectAsString.fromJson<Foo>() 

in kotlin you can

inline fun <reified T> parseData(row :String): T{
   return Gson().fromJson(row, object: TypeToken<T>(){}.type)
}

Fully working solution:

String json = .... //example: mPrefs.getString("list", "");
ArrayList<YouClassName> myTypes = fromJSonList(json, YouClassName.class);


public <YouClassName> ArrayList<YouClassName> fromJSonList(String json, Class<YouClassName> type) {
        Gson gson = new Gson();
        return gson.fromJson(json, TypeToken.getParameterized(ArrayList.class, type).getType());
    }

Well actually i have made extension functions to resolve this , saving a list to SharedPrefrence and retrieve them in anyplace in the app like this :

use this to Save a List to SharedPref. For example :

fun <T> SaveList(key: String?, list: List<T>?) {
val gson = Gson()
val json: String = gson.toJson(list)
getSharedPrefrences(App.getAppContext() as Application).edit().putString(key, json).apply()}

return the list in any place from sharedPref. like this :

fun Context.getList(key: String): String? {
 return getSharedPrefrences(App.getAppContext() as Application).getString(key, null)}

inline fun <reified T : Any> String?.fromJson(): T? = this?.let {
val type = object : TypeToken<T>() {}.type
Gson().fromJson(this, type)}

Usage in Saving and Getting List from Saved one is like :

saveList(Consts.SLIDERS, it.data)  

SetSliderData(this.getList(Consts.SLIDERS).fromJson<MutableList<SliderResponseItem>>()!!)

This is straightforward & simple in Kotlin.

val typeDataModelClass = Array<DataModelClass>::class.java
  this code is json string data to convert in arraylist model 




  String json = getIntent().getExtras().getString("submitQuesList", "");
                Type typeOfObjectsList = new TypeToken<ArrayList<Datum_ques>>() {
                }.getType();
                submitQuesList = new Gson().fromJson(json, typeOfObjectsList);
Related