如何从API解析不规则的JSON字符串

问题描述

您好,我是Android Studio Kotlin的新手,但我一直陷在这个问题中:我有一个由OpenWeatherMap API返回的JSON字符串。过去的link提出了类似的问题,但它是Java。

This is a typical string:

 {
    "coord": {
        "lon": -2.93,"lat": 43.26
    },"weather": [{
        "id": 801,"main": "Clouds","description": "few clouds","icon": "02n"
    }],"base": "stations","main": {
        "temp": 60.69,"feels_like": 62.33,"temp_min": 59,"temp_max": 63,"pressure": 1023,"humidity": 100
    },"visibility": 10000,"wind": {
        "speed": 3.36,"deg": 120
    },"clouds": {
        "all": 20
    },"dt": 1602195029,"sys": {
        "type": 1,"id": 6395,"country": "ES","sunrise": 1602224311,"sunset": 1602265138
    },"timezone": 7200,"id": 3128026,"name": "Bilbao","cod": 200
}

这是我的代码

package com.example.downloadtest

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import org.json.JSONObject
import java.net.URL
import java.util.concurrent.Executors

val executor = Executors.newScheduledThreadPool(5)



class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        doAsync(executorService = executor) {
            //val result = URL("https://httpbin.org/get").readText()
            val result = URL("https://api.openweathermap.org/data/2.5/weather?q=Bilbao,spain&units=imperial&APPID=-------------").readText()
            val textView = findViewById(R.id.txtView) as TextView
            uiThread {
                //textView.setText(result)
                println(result)
                //toast(result)
                val data = StringBuilder()
                val jsonObject = JSONObject(result)
                val jsonArray = jsonObject.optJSONArray("weather")
                println(jsonArray)
                for (i in 0 until jsonArray.length()){
                    val jsonObject = jsonArray.getJSONObject(i)
                    val main = jsonObject.optString("main").toString()
                    val desc = jsonObject.optString("description").toString()
                    val icon = jsonObject.optString("icon").toString()
                    data.append("Bilbao Weather: \n").append(main).append(" : ").append(desc).append(" : ").append(icon)
                    textView.text = data.toString()
                }
            }
        }

    }

}

如您所见,我可以解析字符串的一部分,但不能解析其他任何东西。如果我想解析“国家”或“名称”,我将如何处理?

在获得任何帮助之前先感谢您。

雷。

解决方法

您的json由嵌套对象组成。您必须先访问对象本身,才能访问对象内部。

如果要访问description参数,则首先需要将weather设为对象。与country相同,您需要从sys创建对象。

您可以这样做:

val sys: JSONObject? = jsonObject.optJSONObject("sys") //this can be null (I don't know how consistent is that model)
val country = sys?.optString("country") ?: "" //if sys is null,default to empty string

关于名称,这是初始对象的属性,因此可以像这样轻松地访问它:

val name = jsonObject.optString("name")

要考虑的一件事是:为什么要在.toString()上进行String

函数optString("fieldName","fallback")将始终返回String,如果提供后备功能,它将使用该函数,否则将返回空的String

如果要创建一个对json建模的对象,并使用jackson或任何其他库进行映射,则还应考虑(从长远来看),那么您将像访问其他java / kotlin参数一样访问它们。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...