kotlin 如何从json-file片段中创建对象列表?

iyfjxgzm  于 2023-08-06  发布在  Kotlin
关注(0)|答案(1)|浏览(114)

我想使用json文件从api请求到谷歌表.从请求我得到这样的文件:
{“range”:“'П'!A1:AB986”,“majorDimension”:“ROWS”,“values”:[ [“Т очк а",“О т д а т ь",“а б р а т ь”],[“а в о ды”],[“П л астик”,“",”к а р т“],[“Б а л а ш о в",”т о в“],[”П К",“",“д о к”],[“б а л а ш о в”],[“т аможня”],[],[“е н т р”],[“в е д о м о с т и”,“т ов1”,“р е м”],[“балашо в”],[“М о с к о в с к ий”],[“т а м ожня”,“р е м д о к и”],[],[],[],[],[“Проче е”] ] }
(也许在this picture中更明显)。
但在工作上,我只需要“价值观”。对于“values”中的每个数组,我希望它转换为UserDataModel的数组。
下面是我的代码:UserDataModel.kt

data class UserDataModel(var point:String?, var get: String?, var take: String?, var isSelected: Boolean = false)

字符串
kt(一个片段,其中包含我发出请求的函数)

private fun getDataFromAPI(){
        var url: String = "https://sheets.googleapis.com/v4/spreadsheets/10-yIy1ZuPSjqgmXd7kO9sHobuVlpZHQnz5dMrou0cVs/values/Пн?alt=json&key=${API}"
        val request = okhttp3.Request.Builder().url(url).build()
        val client = OkHttpClient()
            .newBuilder()
            .addInterceptor { chain ->
                val originalRequest = chain.request()
                val builder = originalRequest
                    .newBuilder()
                val newRequest = builder.build()
                chain.proceed(newRequest)
            }.build()
        client.newCall(request).enqueue(object : Callback{
            override fun onFailure(call: Call, e: IOException) {
                Log.d("Mylog", "failed")
                e.printStackTrace()
            }
            override fun onResponse(call: Call, response: okhttp3.Response) {
                DATA_FROM_SHEETS = response.body?.string()!!
                var json = JSONObject(DATA_FROM_SHEETS)
                val gson = Gson()
                val model_list = gson.fromJson(json["values"].toString() , Array<UserDataModel>::class.java)
               Log.d("Mylog", model_list.toString() )
            }
        })

        }


但是当初始化model_list(onResponse()中的字符串4)时,我正在获取“Caused by:java.lang.IllegalStateException:应为开始_OBJECT,但在第1行第3列路径$[0]处为BEGIN_ARRAY "。怎么做才对呢?

wlwcrazw

wlwcrazw1#

序列化不起作用,因为你有一个数组,例如。[ "Пластик", "", "карт" ]没有序列化到对象UserDataModel,因为这不是数组!
我使用一个中间对象来实现这一点,以便从JSON流中轻松读取,并且我不会混合使用JSONObject()Gson

import com.google.gson.Gson

data class UserDataModel(
    val point: String?,
    val get: String?,
    val take: String?,
    var isSelected: Boolean = false
)

data class ReaderModel(val values: List<List<String>>)

fun main(args: Array<String>) {
    val source = """
            { "range": "'Пн'!A1:AB986", "majorDimension": "ROWS", "values": [ [ "Точка", "Отдать", "Забрать" ], [ "Заводы" ], [ "Пластик", "", "карт" ], [ "Балашов", "тов" ], [ "ПЭК", "", "док" ], [ "балашов" ], [ "таможня" ], [], [], [ "", "", "", "", " " ], [], [], [], [], [ "Центр" ], [ "ведомости", "тов1", "рем" ], [ "балашов" ], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [ "Московский" ], [ "таможня", "рем доки" ], [], [], [], [], [], [], [], [], [], [], [], [], [ "Прочее" ] ] }
        """.trimIndent()

    // first read the JSON into this object which has a List of List of Strings
    // if you don't need the range and majorDimension fields, Gson will by default ignore them
    val parsed = Gson().fromJson(source, ReaderModel::class.java)
    println(parsed)

    // now using Kotlin transform that into the desired object
    val models : List<UserDataModel> = parsed.values
        .drop(1) // if the first row contains titles, this is how to ignore that first row
        .map {
            UserDataModel(
                point = if (it.size >= 1) it[0] else null,
                get = if (it.size >= 2) it[1] else null,
                take = if (it.size >= 3) it[2] else null,
            )
        }
        .filter { !it.point.isNullOrBlank() } // if you want it ignore the emtpy/blank nodes
    models.forEach { println(it) }
}

字符串

相关问题