我是Kotlin的新手,我发现Klaxon库可以解析JSON。我找不到如何执行url(http://localhost:8080/items/2),读取JSON字符串并将数据保存到变量并将其打印到控制台。 CreatedAt和UpdatedAt我不需要保存。
来自网址的JSON:
{
"brand": "Ferrero",
"name": "Nutella",
"healthy": false,
"date": "2017-03-14T00:00:00.000Z",
"id": 2,
"createdAt": "2018-03-14T13:33:22.000Z",
"updatedAt": "2018-03-20T21:23:44.000Z"
}
代码:
class DetailItem : AppCompatActivity() {
var itemId : String = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail_item)
itemId = intent.getStringExtra("itemId")
}
override fun onResume() {
super.onResume()
example()
}
private fun parse(name: String) : Any{
val cls = Parser::class.java
val inputStream = cls.getResourceAsStream(name)!!
return Parser().parse(inputStream)!!
}
private fun example(){
val url = "http://192.168.99.100:8080/items/" + itemId
val obj = parse("url") as JsonObject
val brand = obj.string("brand")
val name = obj.string("name")
println(brand + name)
}
答案 0 :(得分:1)
问题是方法cls.getResourceAsStream(name)
返回null
,而!!
运算符会导致NPE被抛出。
为什么cls.getResourceAsStream(name)
会返回null
?之所以会发生这种情况,是因为方法getResourceAsStream
会在您在项目中提供的资源中搜索具有提供的name
的资源(即文件)。
但是,在您的情况下,您希望从URL下载JSON,因此您需要首先执行下载,这将为您提供String
形式的JSON(或者可以转换为a String
),然后使用Parser().parse(yourJsonString) as JsonObject
解析该字符串。
这是一个使用OkHttp库的示例:
import com.beust.klaxon.Klaxon
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
fun main(args: Array<String>) {
val url = "https://jsonplaceholder.typicode.com/posts/1"
val client = OkHttpClient()
val request = Request.Builder()
.url(url)
.build()
println(Thread.currentThread())
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call?, e: IOException?) {
e?.printStackTrace()
}
override fun onResponse(call: Call?, response: Response) {
if (!response.isSuccessful) {
System.err.println("Response not successful")
return
}
val json = response.body()!!.string()
val myData = Klaxon().parse<MyData>(json)
println("Data = $myData")
println(Thread.currentThread())
}
})
// Shutdown the executor as soon as the request is handled
client.dispatcher().executorService().shutdown()
}
data class MyData(val title: String, val userId: Int)
REST API返回的JSON字符串是:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipitsuscipit recusandae consequuntur expedita et cumreprehenderit molestiae ut ut quas totamnostrum rerum est autem sunt rem eveniet architecto"
}
该代码打印:
Thread[main,5,main]
Data = MyData(title=sunt aut facere repellat provident occaecati excepturi optio reprehenderit, userId=1)
Thread[OkHttp https://jsonplaceholder.typicode.com/...,5,main]
请注意,onResponse
回调是在工作线程上而不是在主线程上执行的,因此如果您在Android中使用此代码,则无法从那里更改UI元素(除非你使用runOnUiThread()
或类似的技术)
答案 1 :(得分:1)
我发现这段代码可以解决我的问题。但它是AsyncTask,如何重写它并仅在我想要的时候执行它?
inner class AsyncTaskHandleJson : AsyncTask<String, String, String>() {
override fun doInBackground(vararg url: String?): String {
var text: String
var connection = URL(url[0]).openConnection() as HttpURLConnection
try {
connection.connect()
text = connection.inputStream.use { it.reader().use { reader -> reader.readText() } }
} finally {
connection.disconnect()
}
return text
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
}
}
private fun handleJson(jsonString: String?) {
val jsonObject = JSONObject(jsonString)
val itemIdBrand = findViewById<TextView>(R.id.itemIdBrand)
itemIdBrand.text = jsonObject.getString("brand")
println(jsonObject.getString("brand"))
}