web-dev-qa-db-fra.com

Utiliser Gson dans Kotlin pour analyser un tableau JSON

Essayer d'analyser un tableau JSON dans Kotlin, l'a fait fonctionner pour un objet JSON unique en un objet WeatherObject (extrait de code ci-dessous)

{
"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

}

mais vous ne savez pas comment faire de même si le JSON est un tableau du même objet JSON, c'est-à-dire.

de json array [{}, {}…] à ArrayList <WeatherObject>

quelque chose comme:

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

ayant un problème avec 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
    }

Mise à jour:

a essayé la solution de chandil03, IT IS TRAVAILLANT!) mettez les données de la matrice de test Json et la fonction ici:

a tenté

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
    }

a eu une exception à

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 $

les données du tableau JSON sont comme:

[
{
  "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
}
]
22
lannyf

Vous devez modifier le paramètre dans votre appel de fonction fromJson() comme suit:

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

Vous devez passer Array<WeatherObject>::class.Java Pour le type de classe puis convertir le résultat en List. Pas besoin de changer registerTypeAdapter() appel de fonction.

Vérifiez le code suivant:

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
    }
40
chandil03