Kotlin json parse list

How to parse JSON in Kotlin?

I’m receiving a quite deep JSON object string from a service which I must parse to a JSON object and then map it to classes. How can I transform a JSON string to object in Kotlin? After that the mapping to the respective classes, I was using StdDeserializer from Jackson. The problem arises at the moment the object had properties that also had to be deserialized into classes. I was not able to get the object mapper, at least I didn’t know how, inside another deserializer. Preferably, natively, I’m trying to reduce the number of dependencies I need so if the answer is only for JSON manipulation and parsing it’d be enough.

I haven’t developed in Java. It’s not an error I’m getting. I just don’t know how to do effective parsing in Kotlin natively. All searches always lead to a framework. Java has an org.json.simple. Trusting the autocomplete features of the IDE, Kotlin doesn’t.

The org.json.simple package isn’t native to Java. I guess it’s this library: github.com/fangyidong/json-simple. You could use it with Kotlin as well if you want (although the klaxon library that Jason Bourne suggested might be a better choice for Kotlin).

17 Answers 17

There is no question that the future of parsing in Kotlin will be with kotlinx.serialization. It is part of Kotlin libraries. Version kotlinx.serialization 1.0 is finally released

import kotlinx.serialization.* import kotlinx.serialization.json.JSON @Serializable data class MyModel(val a: Int, @Optional val b: String = "42") fun main(args: Array) < // serializing objects val jsonData = JSON.stringify(MyModel.serializer(), MyModel(42)) println(jsonData) // // serializing lists val jsonList = JSON.stringify(MyModel.serializer().list, listOf(MyModel(42))) println(jsonList) // [] // parsing data back val obj = JSON.parse(MyModel.serializer(), """""") println(obj) // MyModel(a=42, b="42") > 

The problem I have with this is that you can hardly use it with generics. At least I have not figured out how to do so. And I certainly don’t want to use reflection.

Читайте также:  Implement Sticky Header and Footer with CSS

KotlinX Serialization is still in experimental phase, so they introduce breaking changes in new releases. Also, it’s not thread-safe, so your JSON might get corrupted if several threads try to use a single instance of Json (it’s common). Furthermore, there are several open Github issues with the bug label. So, it’s still risky for use in production I would say (unless you’re willing to spend time on fixing potential issues and do not plan to update it frequently). The project is indeed interesting especially for Kotlin Multiplatform projects, but it’s not stable yet.

kotlinlang.org/docs/releases.html shows this plugin many times. It seems to be the best way to work with json in Kotlin.

Klaxon is a lightweight library to parse JSON in Kotlin.

I tried this today after two days of stuffing around with other libraries, and it works really well. Polymorphic support and documentation look good too, after collections it’s the second thing I always test. Great package @Cedric!

if you are looking at doing multi-platform or want the best performance. you should use Kotlinx serialization below.

Example

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

Convert json to Kotlin Bean (use JsonToKotlinClass)

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

The problem with Gson is that it disregards nullability. A val property can easily be null if it’s missing from the JSON. Also, default values are not used at all.

@user3738870 did you find a better alternative? i am frustrated by this behavior of every parser i try

@anshsachdeva Yes, multiple ones, I found moshi the fastest and easiest to use. github.com/square/moshi

Without external library (on Android)

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 foos = Response(jsonString) 

So if this does not require any external libraries, that should mean org.json.JSONObject is part of the standard library right?

I guess it’s an Android thing? I was looking for it in the Kotlin or Java standard library for the JVM.

Oh yes absolutely, I am sorry I forgot to mention that in the answer! Maybe you could use JsonObject if your JVM is running under Java7 (docs.oracle.com/javaee/7/api/javax/json/JsonObject.html)?

Not sure if this is what you need but this is how I did it.

Using 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)

Here’s a sample of the json :

This method requires that class must have default constructor without any params. What if data class have params in constructor like below: data class SomeClass(val param1: Int, val param2: Int) .

@leimenghao You can do this in one line : val categories = SomeClass(param1 = foodJson.getJSONObject(i).getString(«FoodName»),param2 = foodJson.getJSONObject(i).getInt(«Weight»))

Works really well. Just to say, you can use for (i in 0 until foodJson. length()) < instead of for (i in 0..foodJson. length() - 1) < . It does the same, and it's quite more visual

I personally use the Jackson module for Kotlin that you can find here: jackson-module-kotlin.

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

As an example, here is the code to parse the JSON of the Path of Exile skilltree which is quite heavy (84k lines when formatted) :

package util import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.module.kotlin.* import java.io.File data class SkillTreeData( val characterData: Map, val groups: Map, val root: Root, val nodes: List, val extraImages: Map, val min_x: Double, val min_y: Double, val max_x: Double, val max_y: Double, val assets: Map>, val constants: Constants, val imageRoot: String, val skillSprites: SkillSprites, val imageZoomLevels: List ) 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?, val n: List ) data class Root( val g: Int, val o: Int, val oidx: Int, val sa: Int, val da: Int, val ia: Int, val out: List ) 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?, val ascendancyName: String?, val isAscendancyStart: Boolean?, val reminderText: List?, val spc: List, val sd: List, val g: Int, val o: Int, val oidx: Int, val sa: Int, val da: Int, val ia: Int, val out: List ) data class ExtraImage( val x: Double, val y: Double, val image: String ) data class Constants( val classes: Map, val characterAttributes: Map, 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 ) data class SkillSprites( val normalActive: List, val notableActive: List, val keystoneActive: List, val normalInactive: List, val notableInactive: List, val keystoneInactive: List, val mastery: List ) private fun convert( jsonFile: File ) < val mapper = jacksonObjectMapper() mapper.configure( DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true ) val skillTreeData = mapper.readValue( jsonFile ) println("Conversion finished !") > fun main( args : Array ) < val jsonFile: File = File( """rawSkilltree.json""" ) convert( jsonFile ) 

Given your description, I believe it matches your needs.

Источник

How to parse json in kotlin?

Parsing JSON in Kotlin requires the use of libraries to handle the conversion from JSON strings to Kotlin objects. The process of parsing JSON is an important task when working with web services, APIs or simply receiving data from a remote source in a JSON format. There are several libraries available in Kotlin that can be used to parse JSON, each with its own advantages and disadvantages. In this article, we will explore a few popular libraries and their methods for parsing JSON in Kotlin.

Method 1: Using GSON Library

To parse JSON in Kotlin using the GSON library, follow the steps below:

  1. Add the GSON library to your project by adding the following dependency to your build.gradle file:
  1. Create a data class that represents the JSON object you want to parse. For example, if you have a JSON object with the following structure:
 "name": "John Doe", "age": 30, "email": "johndoe@example.com" >

You can create a data class like this:

data class User(val name: String, val age: Int, val email: String)
val gson = Gson() val jsonString = "" val user = gson.fromJson(jsonString, User::class.java)

In the code above, we first create an instance of the Gson class. We then create a JSON string that we want to parse. Finally, we use the fromJson method of the Gson class to parse the JSON string into an instance of our User data class.

println(user.name) // Output: John Doe println(user.age) // Output: 30 println(user.email) // Output: johndoe@example.com

That's it! You have successfully parsed a JSON string using the GSON library in Kotlin.

Method 2: Using Jackson Library

To parse JSON in Kotlin using the Jackson library, follow these steps:

  1. Create a data class that matches the structure of your JSON data. For example, if your JSON data looks like this:

Then you can create a data class like this:

data class Person(val name: String, val age: Int, val city: String)
  1. Use the ObjectMapper class from the Jackson library to parse the JSON data into your data class. For example:
import com.fasterxml.jackson.databind.ObjectMapper val json = """< "name": "John", "age": 30, "city": "New York" >""" val objectMapper = ObjectMapper() val person = objectMapper.readValue(json, Person::class.java)

In the above code, we first define a JSON string. Then we create an instance of the ObjectMapper class. Finally, we use the readValue method to parse the JSON string into a Person object.

  1. You can also use the ObjectMapper class to parse JSON arrays. For example, if your JSON data looks like this:

Then you can create a data class for a single person like before, and then parse the JSON array like this:

import com.fasterxml.jackson.databind.ObjectMapper val json = """[ < "name": "John", "age": 30, "city": "New York" >, < "name": "Jane", "age": 25, "city": "San Francisco" >]""" val objectMapper = ObjectMapper() val people = objectMapper.readValue(json, ArrayPerson>::class.java)

In the above code, we use the readValue method with the Array class to parse the JSON array into an array of Person objects.

That's it! You now know how to parse JSON in Kotlin using the Jackson library.

Method 3: Using Moshi Library

To parse JSON in Kotlin using Moshi Library, you can follow these steps:

  1. Create a data class that represents the JSON object you want to parse. For example, if you have a JSON object like this:
 "name": "John Doe", "age": 30, "email": "johndoe@example.com" >

You can create a data class like this:

data class User( val name: String, val age: Int, val email: String )
  1. Parse the JSON using Moshi. You can create a Moshi instance and use it to parse the JSON string into a User object like this:
val moshi = Moshi.Builder().build() val jsonAdapter = moshi.adapter(User::class.java) val user = jsonAdapter.fromJson(jsonString)

Where jsonString is the JSON string you want to parse.

  1. You can also serialize a User object to JSON using Moshi. You can create a Moshi instance and use it to serialize the User object into a JSON string like this:
val moshi = Moshi.Builder().build() val jsonAdapter = moshi.adapter(User::class.java) val jsonString = jsonAdapter.toJson(user)

Where user is the User object you want to serialize.

Here's an example code that shows how to parse JSON using Moshi:

import com.squareup.moshi.Moshi data class User( val name: String, val age: Int, val email: String ) fun main()  val jsonString = """ < "name": "John Doe", "age": 30, "email": "johndoe@example.com" >""".trimIndent() val moshi = Moshi.Builder().build() val jsonAdapter = moshi.adapter(User::class.java) val user = jsonAdapter.fromJson(jsonString) println(user?.name) // Output: John Doe println(user?.age) // Output: 30 println(user?.email) // Output: johndoe@example.com >

And here's an example code that shows how to serialize a User object to JSON using Moshi:

import com.squareup.moshi.Moshi data class User( val name: String, val age: Int, val email: String ) fun main()  val user = User("John Doe", 30, "johndoe@example.com") val moshi = Moshi.Builder().build() val jsonAdapter = moshi.adapter(User::class.java) val jsonString = jsonAdapter.toJson(user) println(jsonString) // Output: >

That's it! You can now parse and serialize JSON using Moshi in Kotlin.

Источник

Оцените статью