我从一个服务接收到一个相当深的JSON对象字符串,我必须解析为JSON对象,然后将其映射到类。
如何将JSON字符串转换为Kotlin对象?
在映射到各自的类之后,我使用了来自Jackson的StdDeserializer。当对象的属性也必须被反序列化为类时,问题就出现了。我无法在另一个反序列化器中获得对象映射器,至少我不知道如何获得。
最好是,在本地,我试图减少我需要的依赖项的数量,所以如果答案只是JSON操作和解析它就足够了。
我从一个服务接收到一个相当深的JSON对象字符串,我必须解析为JSON对象,然后将其映射到类。
如何将JSON字符串转换为Kotlin对象?
在映射到各自的类之后,我使用了来自Jackson的StdDeserializer。当对象的属性也必须被反序列化为类时,问题就出现了。我无法在另一个反序列化器中获得对象映射器,至少我不知道如何获得。
最好是,在本地,我试图减少我需要的依赖项的数量,所以如果答案只是JSON操作和解析它就足够了。
当前回答
没有外部库(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)
其他回答
这使用kotlinx。像以利沙的回答。与此同时,该项目已经过了1.0版本,因此API已经发生了变化。注意,例如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的数据类是一个主要保存数据的类,并具有自动定义的成员. tostring()和其他方法(例如解构声明)。
首先。
你可以使用JSON到Kotlin数据类转换插件在Android Studio JSON映射到POJO类(Kotlin数据类)。 这个插件将根据JSON注释你的Kotlin数据类。
然后可以使用GSON转换器将JSON转换为Kotlin。
遵循这个完整的教程: Kotlin Android JSON解析教程
如果你想手动解析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"))
}
我个人在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
根据你的描述,我相信符合你的需要。
解析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") }
Person是一个模型/数据类,像这样
data class Person(val name: String, val age: Int, val messages: List) {
}
不知道这是不是你需要的但我就是这么做的。
使用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的示例:
{“食品”: [{“食品名称”: “苹果”,“重量”: “110” } ]}