web-dev-qa-db-fra.com

Comment analyser JSON dans Kotlin?

Je reçois une chaîne d'objet JSON assez profonde d'un service que je dois analyser avec un objet JSON, puis mapper celui-ci sur des classes.

Comment puis-je transformer une chaîne JSON en objet dans Kotlin?

Après cela, le mappage aux classes respectives, j’utilisais StdDeserializer de Jackson. Le problème se pose au moment où l'objet avait des propriétés qui devaient également être désérialisées en classes. Je n'ai pas pu obtenir le mappeur d'objets, du moins je ne savais pas comment, à l'intérieur d'un autre désérialiseur.

Merci d'avance pour votre aide. De manière native, j'essaie de réduire le nombre de dépendances dont j'ai besoin, donc si la réponse ne concerne que la manipulation JSON et son analyse, cela suffirait.

65
AJ_1310

Vous pouvez utiliser cette bibliothèque https://github.com/cbeust/klaxon

Klaxon est une bibliothèque légère permettant d’analyser JSON dans Kotlin.

42
Jason Bourne

Il ne fait aucun doute que l'avenir de l'analyse syntaxique dans Kotlin sera avec kotlinx.serialization. Il fait partie des bibliothèques Kotlin. Il est encore au moment de l'écriture en phase d'incubateur.

https://github.com/Kotlin/kotlinx.serialization

import kotlinx.serialization.*
import kotlinx.serialization.json.JSON

@Serializable
data class MyModel(val a: Int, @Optional val b: String = "42")

fun main(args: Array<String>) {

    // serializing objects
    val jsonData = JSON.stringify(MyModel.serializer(), MyModel(42))
    println(jsonData) // {"a": 42, "b": "42"}

    // serializing lists
    val jsonList = JSON.stringify(MyModel.serializer().list, listOf(MyModel(42)))
    println(jsonList) // [{"a": 42, "b": "42"}]

    // parsing data back
    val obj = JSON.parse(MyModel.serializer(), """{"a":42}""")
    println(obj) // MyModel(a=42, b="42")
}
55
Elisha Sterngold

Sans bibliothèque externe (sous Android)

Pour analyser ceci:

val jsonString = """
    {
       "type":"Foo",
       "data":[
          {
             "id":1,
             "title":"Hello"
          },
          {
             "id":2,
             "title":"World"
          }
       ]
    }        
"""

Utilisez ces classes:

import org.json.JSONObject

class Response(json: String) : JSONObject(json) {
    val type: String? = this.optString("type")
    val data = this.optJSONArray("data")
            ?.let { 0.until(it.length()).map { i -> it.optJSONObject(i) } } // returns an array of JSONObject
            ?.map { Foo(it.toString()) } // transforms each JSONObject of the array into Foo
}

class Foo(json: String) : JSONObject(json) {
    val id = this.optInt("id")
    val title: String? = this.optString("title")
}

Usage:

val foos = Response(jsonString)
19
frouo

Je ne sais pas si c'est ce dont vous avez besoin, mais c'est comme ça que je l'ai fait.

Utilisation de import org.json.JSONObject:

    val jsonObj = JSONObject(json.substring(json.indexOf("{"), json.lastIndexOf("}") + 1))
    val foodJson = jsonObj.getJSONArray("Foods")
    for (i in 0..foodJson!!.length() - 1) {
        val categories = FoodCategoryObject()
        val name = foodJson.getJSONObject(i).getString("FoodName")
        categories.name = name
    }

Voici un exemple du json: {"Foods": {"FoodName": "Apple", "Weight": "110"}}

16
markB

Vous pouvez utiliser Gson.

Exemple

Étape 1

Ajouter compiler

compile 'com.google.code.gson:gson:2.8.2'

Étape 2

Convertir JSON en Kotlin Bean (utilisez JsonToKotlinClass )

Comme ça

Json données

{
"timestamp": "2018-02-13 15:45:45",
"code": "OK",
"message": "user info",
"path": "/user/info",
"data": {
    "userId": 8,
    "avatar": "/uploads/image/20180115/1516009286213053126.jpeg",
    "nickname": "",
    "gender": 0,
    "birthday": 1525968000000,
    "age": 0,
    "province": "",
    "city": "",
    "district": "",
    "workStatus": "Student",
    "userType": 0
},
"errorDetail": null
}

Kotlin Bean

class MineUserEntity {

    data class MineUserInfo(
        val timestamp: String,
        val code: String,
        val message: String,
        val path: String,
        val data: Data,
        val errorDetail: Any
    )

    data class Data(
        val userId: Int,
        val avatar: String,
        val nickname: String,
        val gender: Int,
        val birthday: Long,
        val age: Int,
        val province: String,
        val city: String,
        val district: String,
        val workStatus: String,
        val userType: Int
    )
}

Étape 3

Utilisez Gson

var gson = Gson()
var mMineUserEntity = gson?.fromJson(response, MineUserEntity.MineUserInfo::class.Java)
15
KeLiuyue

Personnellement, j'utilise le module Jackson pour Kotlin que vous pouvez trouver ici: jackson-module-kotlin .

implementation "com.fasterxml.jackson.module:jackson-module-kotlin:$version"

À titre d’exemple, voici le code permettant d’analyser le code JSON de l’arborescence de compétences du Chemin de l’exil qui est assez lourde (84 000 lignes lors de la mise en forme):

Code Kotlin:

package util

import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.kotlin.*
import Java.io.File

data class SkillTreeData( val characterData: Map<String, CharacterData>, val groups: Map<String, Group>, val root: Root,
                          val nodes: List<Node>, val extraImages: Map<String, ExtraImage>, val min_x: Double,
                          val min_y: Double, val max_x: Double, val max_y: Double,
                          val assets: Map<String, Map<String, String>>, val constants: Constants, val imageRoot: String,
                          val skillSprites: SkillSprites, val imageZoomLevels: List<Int> )


data class CharacterData( val base_str: Int, val base_dex: Int, val base_int: Int )

data class Group( val x: Double, val y: Double, val oo: Map<String, Boolean>?, val n: List<Int> )

data class Root( val g: Int, val o: Int, val oidx: Int, val sa: Int, val da: Int, val ia: Int, val out: List<Int> )

data class Node( val id: Int, val icon: String, val ks: Boolean, val not: Boolean, val dn: String, val m: Boolean,
                 val isJewelSocket: Boolean, val isMultipleChoice: Boolean, val isMultipleChoiceOption: Boolean,
                 val passivePointsGranted: Int, val flavourText: List<String>?, val ascendancyName: String?,
                 val isAscendancyStart: Boolean?, val reminderText: List<String>?, val spc: List<Int>, val sd: List<String>,
                 val g: Int, val o: Int, val oidx: Int, val sa: Int, val da: Int, val ia: Int, val out: List<Int> )

data class ExtraImage( val x: Double, val y: Double, val image: String )

data class Constants( val classes: Map<String, Int>, val characterAttributes: Map<String, Int>,
                      val PSSCentreInnerRadius: Int )

data class SubSpriteCoords( val x: Int, val y: Int, val w: Int, val h: Int )

data class Sprite( val filename: String, val coords: Map<String, SubSpriteCoords> )

data class SkillSprites( val normalActive: List<Sprite>, val notableActive: List<Sprite>,
                         val keystoneActive: List<Sprite>, val normalInactive: List<Sprite>,
                         val notableInactive: List<Sprite>, val keystoneInactive: List<Sprite>,
                         val mastery: List<Sprite> )

private fun convert( jsonFile: File ) {
    val mapper = jacksonObjectMapper()
    mapper.configure( DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true )

    val skillTreeData = mapper.readValue<SkillTreeData>( jsonFile )
    println("Conversion finished !")
}

fun main( args : Array<String> ) {
    val jsonFile: File = File( """rawSkilltree.json""" )
    convert( jsonFile )

JSON (non formaté): http://filebin.ca/3B3reNQf3KXJ/rawSkilltree.json

Compte tenu de votre description, je pense que cela correspond à vos besoins.

11
Neurf

Pour convertir JSON en Kotlin, utilisez http://www.json2kotlin.com/

Vous pouvez aussi utiliser Android plugin Studio. Fichier> Paramètres, sélectionnez Plugins dans l'arborescence de gauche, appuyez sur "Parcourir les référentiels ...", recherchez " JsonToKotlinClass ", sélectionnez-le et cliquez dessus. bouton vert "Installer".

plugin

Après le redémarrage, vous pouvez l'utiliser. Vous pouvez créer une classe avec File > New > JSON To Kotlin Class (JsonToKotlinClass). Une autre façon consiste à appuyer sur Alt + K.

enter image description here

Ensuite, vous verrez une boîte de dialogue pour coller JSON.

En 2018, j'ai dû ajouter package com.my.package_name au début d'un cours.

3
CoolMind

Tout d'abord.

Vous pouvez utiliser le plug-in de conversion de classes JSON vers Kotlin Data dans Android Studio pour le mappage JSON vers les classes POJO (classe de données kotlin). Ce plugin annotera votre classe de données Kotlin selon JSON.

Ensuite, vous pouvez utiliser le convertisseur GSON pour convertir JSON en Kotlin.

Suivez ce didacticiel complet: Kotlin Android Didacticiel d'analyse JSON

Si vous voulez analyser json manuellement.

val **sampleJson** = """
  [
  {
   "userId": 1,
   "id": 1,
   "title": "sunt aut facere repellat provident occaecati excepturi optio 
    reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita"
   }]
   """

Code à analyser au-dessus du tableau JSON et de son objet à l'index 0.

var jsonArray = JSONArray(sampleJson)
for (jsonIndex in 0..(jsonArray.length() - 1)) {
Log.d("JSON", jsonArray.getJSONObject(jsonIndex).getString("title"))
}
3
Hammad Tariq

http://www.jsonschema2pojo.org/ Bonjour, vous pouvez utiliser ce site Web pour convertir de json en pojo.
control + Alt + shift + k

Après cela, vous pouvez convertir manuellement cette classe de modèles en classe de modèles kotlin. avec l'aide du raccourci ci-dessus.

1
kundan kamal

Un peu tard, mais peu importe.

Si vous préférez analyser JSON avec JavaScript comme si vous utilisiez la sémantique de Kotlin, je recommande JSONKraken , dont je suis l'auteur.

Les suggestions et opinions sur le sujet sont très appréciées!

0
Facundo Garcia