Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Gson in Kotlin to parse JSON array

Trying to parse JSON array in Kotlin, made it work for single JSON object to a WeatherObject object (code snippet below)

{ "coord": {     "lon": -2.93,     "lat": 43.26 },  "weather": [{     "id": 802,     "main": "Clouds",     "description": "scattered clouds",     "icon": "03d" }],  "main": {     "temp": 283.681,     "temp_min": 283.681,     "temp_max": 283.681,     "pressure": 991.72,     "sea_level": 1034.92,     "grnd_leve": 991.72,     "humidity": 98 }, "wind": {     "speed": 1.07,     "deg": 144.001 },  "dt": 1429773245, "id": 3128026, "name": "Bilbao", "cod": 200 

}

but not sure how to do the same if the JSON is a array of same JSON object, i.e.

from json array [ {}, {} …] to ArrayList<WeatherObject >

something like:

fun getWeatherObjectArrayFromJson(jsonStr: String): ArrayList&lt;WeatherObject &gt 

having problem with gsonBuilder.registerTypeAdapter(ArrayList<WeatherObject &gt::class.java, WeatherDeserializer())

class WeatherObject {      var main: String = ""     var description: String = ""     var temp: Float = 0.0f     var tempMax: Float = 0.0f     var tempMin: Float = 0.0f     var humidity: Int = 0     var wind: WindObject? = null  }  class WeatherDeserializer : JsonDeserializer<WeatherObject> {      override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): WeatherObject? {         val jsonObj = json as JsonObject          val wheather = WeatherObject()         val wind = WindObject()          val jsonWeatherArray = jsonObj.getAsJsonArray("weather").get(0)         val jsonMainObj = jsonObj.getAsJsonObject("main")         val jsonWindObj = jsonObj.getAsJsonObject("wind")          wheather.main = jsonWeatherArray.asJsonObject.get("main").asString         wheather.description = jsonWeatherArray.asJsonObject.get("description").asString         wheather.temp = jsonMainObj.get("temp").asFloat         wheather.tempMax = jsonMainObj.get("temp_max").asFloat         wheather.tempMin = jsonMainObj.get("temp_min").asFloat         wheather.humidity = jsonMainObj.get("humidity").asInt         wind.speed = jsonWindObj.get("speed").asFloat         wind.deg = jsonWindObj.get("deg").asFloat         wheather.wind = wind          return wheather      } }  fun getWeatherObjectFromJson(jsonStr: String): WeatherObject {          var stringReader: StringReader = StringReader(jsonStr)         var jsonReader: JsonReader = JsonReader(stringReader)          val gsonBuilder = GsonBuilder().serializeNulls()         gsonBuilder.registerTypeAdapter(WeatherObject::class.java, WeatherDeserializer())         val gson = gsonBuilder.create()          val weather: WeatherObject = gson.fromJson(jsonReader, WeatherObject::class.java)          return weather     } 

Update:

tried the solution from chandil03, IT IS WORKING! put the testing json array data and the function here:

tried

fun getWeatherObjectFromJsonArray(jsonArrayStr: String): List<WeatherObject> {          var stringReader: StringReader = StringReader(jsonStr)         //var jsonReader: JsonReader = JsonReader(stringReader)          val gsonBuilder = GsonBuilder().serializeNulls()         gsonBuilder.registerTypeAdapter(WeatherObject::class.java, WeatherDeserializer())         val gson = gsonBuilder.create()          val weatherList: List<WeatherObject> = gson.fromJson(stringReader , Array<WeatherObject>::class.java).toList()         //val weatherList: List<WeatherObject> = gson.fromJson(jsonReader, Array<WeatherObject>::class.java).toList          return weatherList     } 

got exception at

val weatherList: List<WeatherObject> = gson.fromJson(stringReader , Array<WeatherObject>::class.java).toList()  com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ 

the json array data is like:

[ {   "coord": {     "lon": -2.93,     "lat": 43.26   },    "weather": [{     "id": 802,     "main": "Clouds",     "description": "scattered clouds",     "icon": "03d"   }],    "main": {     "temp": 283.681,     "temp_min": 283.681,     "temp_max": 283.681,     "pressure": 991.72,     "sea_level": 1034.92,     "grnd_leve": 991.72,     "humidity": 98   },   "wind": {     "speed": 1.07,     "deg": 144.001   },   "clouds": {     "all": 36   },   "dt": 1429773245,   "id": 3128026,   "name": "Bilbao",   "cod": 200 },   {   "coord": {     "lon": -2.93,     "lat": 43.26   },    "weather": [{     "id": 802,     "main": "Clouds",     "description": "scattered clouds",     "icon": "03d"   }],    "main": {     "temp": 283.681,     "temp_min": 283.681,     "temp_max": 283.681,     "pressure": 991.72,     "sea_level": 1034.92,     "grnd_leve": 991.72,     "humidity": 98   },   "wind": {     "speed": 1.07,     "deg": 144.001   },   "clouds": {     "all": 36   },   "dt": 1429773245,   "id": 3128026,   "name": "Bilbao",   "cod": 200 } ] 
like image 505
lannyf Avatar asked Aug 10 '17 01:08

lannyf


People also ask

How do I parse JSON array in Kotlin?

You can use JSON to Kotlin Data class converter plugin in Android Studio for JSON mapping to POJO classes (kotlin data class). This plugin will annotate your Kotlin data class according to JSON. Then you can use GSON converter to convert JSON to Kotlin. If you want to parse json manually.

Does GSON work with Kotlin?

Kotlin Data Classes are great; they're concise, they're null-safe. Gson is great as well; it's a de-facto standard for JSON parsing on Android for a good reason.


1 Answers

You need to change parameter in your fromJson() function call like following:

val weatherList: List<WeatherObject> = gson.fromJson(stringReader , Array<WeatherObject>::class.java).toList() 

You need to pass Array<WeatherObject>::class.java for class type and then convert result into List. No need to change registerTypeAdapter() function call.

Check following code:

fun getWeatherObjectFromJson(jsonStr: String): List<WeatherObject> {          var stringReader: StringReader = StringReader(jsonStr)         var jsonReader: JsonReader = JsonReader(stringReader)          val gsonBuilder = GsonBuilder().serializeNulls()         gsonBuilder.registerTypeAdapter(WeatherObject::class.java, WeatherDeserializer())         val gson = gsonBuilder.create()         val weatherList: List<WeatherObject> = gson.fromJson(stringReader , Array<WeatherObject>::class.java).toList()          return weatherList     } 
like image 179
chandil03 Avatar answered Oct 01 '22 20:10

chandil03