2017-08-10 2 views
2

essayant d'analyser tableau JSON dans Kotlin, fait fonctionner pour seul objet JSON à un objet WeatherObject (snippet de code ci-dessous)utilisant Gson à Kotlin pour analyser tableau JSON

{ 
"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 pas sûr comment faire la même chose si le JSON est un tableau de même objet JSON, à savoir

de tableau JSON [{}, {} ...] pour Arraylist <WeatherObject>

quelque chose comme:

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

ayant un problème 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, C'EST DE TRAVAIL! mettre les données du tableau JSON de test et la fonction ici:

a essayé

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 
    } 

mais j'ai 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 est 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 
} 
] 

Répondre

7

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

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

Vous devez passer Array<WeatherObject>::class.java pour le type de classe et puis le convertir en résultat 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 
    } 
+0

merci chandil03! mais ayant un problème avec la classe WeatherDeserializer: JsonDeserializer , qui traite avec un seul objet json, comment ça marche avec la chaîne json qui a un tableau des mêmes objets json, a-t-elle besoin de définir une version tableau du désérialiseur ? – lannyf

+0

@lannyf Non, le code mentionné ci-dessus fonctionne uniquement avec une chaîne contenant un tableau d'objet météo. Je l'ai vérifié. Changé requis en une seule ligne. – chandil03

+0

essayé avec votre fonction, il a obtenu l'exception. Je mets à jour la fonction et le datagramme de json dans la question. – lannyf