如何从 API 中解析不规则的 JSON 字符串
How to parse an irregular JSON string from an API
你好,我是 Android Studio Kotlin 的新手,我被困在这个问题上:我有一个由 OpenWeatherMap 返回的 JSON 字符串 API.A 类似的问题出现在过去 ,但现在是 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")
需要考虑的一件事是:你为什么在 String
上做 .toString()
?
函数 optString("fieldName", "fallback")
将始终 return 一个 String
,如果您提供后备,它将使用它,否则它将 return 一个空的 String
你还应该考虑(在长 运行 上)如果你想创建一个模型 json 的对象,并用 jackson 或任何其他库映射它,那么你会像访问任何其他 java/kotlin 参数一样访问它们。
你好,我是 Android Studio Kotlin 的新手,我被困在这个问题上:我有一个由 OpenWeatherMap 返回的 JSON 字符串 API.A 类似的问题出现在过去
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")
需要考虑的一件事是:你为什么在 String
上做 .toString()
?
函数 optString("fieldName", "fallback")
将始终 return 一个 String
,如果您提供后备,它将使用它,否则它将 return 一个空的 String
你还应该考虑(在长 运行 上)如果你想创建一个模型 json 的对象,并用 jackson 或任何其他库映射它,那么你会像访问任何其他 java/kotlin 参数一样访问它们。