如何在Kotlin解析JSON ?

我从一个服务接收到一个相当深的JSON对象字符串,我必须解析为JSON对象,然后将其映射到类。

如何将JSON字符串转换为Kotlin对象?

在映射到各自的类之后,我使用了来自Jackson的StdDeserializer。当对象的属性也必须被反序列化为类时,问题就出现了。我无法在另一个反序列化器中获得对象映射器,至少我不知道如何获得。

最好是,在本地,我试图减少我需要的依赖项的数量,所以如果答案只是JSON操作和解析它就足够了。

439017 次浏览

你可以使用这个库https://github.com/cbeust/klaxon

Klaxon是一个轻量级库,用于在Kotlin中解析JSON。

不知道这是不是你需要的但我就是这么做的。

使用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
}

下面是json的示例:

{"食物"食物名称"苹果"重量";}]}

我个人使用Kotlin的Jackson模块,你可以在这里找到:jackson-module-kotlin

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

举个例子,下面是解析《流放之路》技能树JSON的代码,它相当重(格式化时84k行):

芬兰湾的科特林代码:

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(非格式化):http://filebin.ca/3B3reNQf3KXJ/rawSkilltree.json

根据你的描述,我相信符合你的需要。

从这里下载deme的源代码(android kotlin中的Json解析)

添加这个依赖:

compile 'com.squareup.okhttp3:okhttp:3.8.1'

调用api函数:

 fun run(url: String) {
dialog.show()
val request = Request.Builder()
.url(url)
.build()


client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
dialog.dismiss()


}


override fun onResponse(call: Call, response: Response) {
var str_response = response.body()!!.string()
val json_contact:JSONObject = JSONObject(str_response)


var jsonarray_contacts:JSONArray= json_contact.getJSONArray("contacts")


var i:Int = 0
var size:Int = jsonarray_contacts.length()


al_details= ArrayList();


for (i in 0.. size-1) {
var json_objectdetail:JSONObject=jsonarray_contacts.getJSONObject(i)




var model:Model= Model();
model.id=json_objectdetail.getString("id")
model.name=json_objectdetail.getString("name")
model.email=json_objectdetail.getString("email")
model.address=json_objectdetail.getString("address")
model.gender=json_objectdetail.getString("gender")


al_details.add(model)




}


runOnUiThread {
//stuff that updates ui
val obj_adapter : CustomAdapter
obj_adapter = CustomAdapter(applicationContext,al_details)
lv_details.adapter=obj_adapter
}


dialog.dismiss()


}


})

你可以使用Gson

例子

步骤1

添加编译

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

步骤2

将json转换为Kotlin Bean(使用JsonToKotlinClass)

像这样

Json数据

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

步骤3

使用Gson

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

毫无疑问,Kotlin中解析的未来将是kotlinx.serialization。它是Kotlin库的一部分。kotlinx版本。序列化1.0终于发布了

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")
}

首先。

你可以使用JSON到Kotlin数据类转换插件在Android Studio JSON映射到POJO类(Kotlin数据类)。 这个插件将根据JSON注释你的Kotlin数据类

然后可以使用GSON转换器将JSON转换为Kotlin。

完整教程: Kotlin Android JSON解析教程 < / p >

如果你想手动解析json。

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

JSON数组及其对象在索引0处的解析代码。

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

没有外部库(Android)

解析如下:

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

使用这些类:

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")
}

用法:

val foos = Response(jsonString)

http://www.jsonschema2pojo.org/ 嗨,你可以使用这个网站转换json到pojo.
控制+ Alt + shift + k < / p >

之后,您可以手动将该模型类转换为kotlin模型类。借助上述快捷方式。

如果你更喜欢解析JSON而不是使用Kotlin语法的类似javascript的结构,我推荐JSONKraken,我是它的作者。

你可以这样做:

val json: JsonValue = JsonKraken.deserialize("""{"getting":{"started":"Hello World"}}""")
println(JsonKraken.serialize(json)) //prints: {"getting":{"started":"Hello World"}}
println(json["getting"]["started"].cast<String>()) //prints: Hello World

对此事的建议和意见,非常感谢!

使用http://www.json2kotlin.com/将JSON转换为Kotlin

你也可以使用Android Studio插件。文件>设置,在左侧树中选择Plugins,按“浏览存储库…”,搜索“JsonToKotlinClass”,选中它,点击绿色按钮“安装”。

plugin

在AS重启后,您可以使用它。你可以用File > New > JSON To Kotlin Class (JsonToKotlinClass)创建一个类。另一种方法是按Alt + K。

enter image description here

然后您将看到一个粘贴JSON的对话框。

在2018年,我不得不在类的开头添加package com.my.package_name

它像以利沙的回答一样使用kotlinx.serialization。与此同时,该项目已经过了1.0版本,因此API已经发生了变化。注意,e.g. JSON.parse被重命名为Json.decodeFromString。它也在Kotlin 1.4.0开始的gradle 不同的中被导入:

dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0"
}
apply plugin: 'kotlinx-serialization'

使用示例:

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
@Serializable
data class Point(val x: Int, val y: Int)


val pt = Json.decodeFromString<Point>("""{"y": 1, "x": 2}""")
val str = Json.encodeToString(pt)  // type can be inferred!


val ilist = Json.decodeFromString<List<Int>>("[-1, -2]")
val ptlist = Json.decodeFromString<List<Point>>(
"""[{"x": 3, "y": 4}, {"x": 5, "y": 6}]"""
)

你可以为可空字段和可选字段使用可空类型(T?):

@Serializable
data class Point2(val x: Int, val y: Int? = null)


val nlist = Json.decodeFromString<List<Point2>>(
"""[{"x": 7}, {"x": 8, "y": null}, {"x": 9, "y": 0}]"""
)

Kotlin的data class是一个主要保存数据的类,它具有自动定义的成员、.toString()和其他方法(例如解构声明)。

芬兰湾的科特林序列化

Kotlin特定的库由JetBrains支持的所有平台- Android, JVM, JavaScript,本机。

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

苎麻

Moshi是一个JSON库,适用于Android和Java。

https://github.com/square/moshi

杰克逊

https://github.com/FasterXML/jackson

Gson

最受欢迎,但几乎< >强弃用< / >强

https://github.com/google/gson

JSON到Java

http://www.jsonschema2pojo.org/

JSON到Kotlin

IntelliJ插件- https://plugins.jetbrains.com/plugin/9960-json-to-kotlin-class-jsontokotlinclass-

GSON是Android和Web平台在Kotlin项目中解析JSON的一个很好的选择。此库由谷歌开发。 https://github.com/google/gson < / p >

1. 首先,将GSON添加到项目中:

dependencies {
implementation 'com.google.code.gson:gson:2.8.9'
}

2. 现在你需要将JSON转换为Kotlin Data类:

复制您的JSON,并前往这个(https://json2kt.com)网站,并将您的JSON粘贴到输入JSON框。在适当的框中写入包(例如:com.example.appName)和类名(例如:UserData)。这个网站将在下面显示你的数据类的实时预览,你也可以在一个zip文件中下载所有的类。

下载完所有类后,解压zip文件&把它们放到你的项目中。

3.现在像下面这样解析:

val myJson = """
{
"user_name": "john123",
"email": "john@example.com",
"name": "John Doe"
}
""".trimIndent()


val gson = Gson()
var mUser = gson.fromJson(myJson, UserData::class.java)
println(mUser.userName)

:完成)

解析JSON字符串到Kotlin对象

正如其他人推荐的那样,Gson图书馆是最简单的方法!

如果文件在资产的文件夹中,你可以这样做,首先添加

dependencies {
implementation 'com.google.code.gson:gson:2.9.0'
}

然后从资产中获取一个文件:

jsonString = context.assets.open(fileName).bufferedReader().use { it.readText() }

然后使用Gson:

val gson = Gson()
val listPersonType = object : TypeToken<List<Person>>() {}.type
var persons: List<Person> = gson.fromJson(jsonFileString, listPersonType)
persons.forEachIndexed { idx, person -> Log.i("data", "> Item $idx:\n$person") }

其中PersonModel/Data class,像这样

data class Person(val name: String, val age: Int, val messages: List) {
}

似乎Kotlin没有任何内置方法,因为在许多情况下,它只是从Java中导入并实现了一些工具。在尝试了许多包之后,最终这个包运行正常。这个fastjson来自阿里巴巴,非常容易使用。内部构建gradle依赖:

implementation 'com.alibaba:fastjson:1.1.67.android'

在你的Kotlin代码中:

import com.alibaba.fastjson.JSON
var jsonDecodedMap: Map<String, String> =
JSON.parse(yourStringValueHere) as Map<String, String>;