简体   繁体   English

Kotlin Android,从HTTP请求解析Json

[英]Kotlin Android, Parsing Json from HTTP request

I'm trying to parse json from an http request in a Kotlin Android file. 我正在尝试从Kotlin Android文件中的http请求解析json。 I'd really like to avoid having to specifically use GSON to deserialize into a class every time I make an http request if I just want to pull a single element. 如果我只想提取一个元素,我真的想避免每次我发出http请求时都必须专门使用GSON反序列化为一个类。 I come from javascript land where parsing json into object notation comes right out of the box, so this has caused irritation. 我来自javascript领域,将json解析为对象符号是开箱即用的,所以这引起了人们的不满。

Here is what I am working with currently. 这是我目前正在使用的工具。 I'm using Fuel to make the http request and Klaxon to try and parse it. 我正在使用Fuel发出http请求,并使用Klaxon尝试解析它。

    Fuel.get("http://api.openweathermap.org/data/2.5/weather?q=Austin,us&appid=MYAPIKEYSUPERDUPERSECRET").responseString { request, response, result ->
            //do something with response
            result.fold({ d ->
                  println("value of d")
                  println(d)
                  val parser = Parser()
                  val stringBuilder = StringBuilder(d)
                  val json: JsonObject = parser.parse(stringBuilder) as JsonObject
                  println("Weather : ${json.string("weather")}")
            }, { err ->
                //do something with error
            })
        }

So when I run the above I get the following. 因此,当我运行上面的代码时,我得到以下内容。

From my println("value of d") I get 从我的println("value of d")我得到

{"coord":{"lon":-97.74,"lat":30.27},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"base":"stations","main":{"temp":297.15,"pressure":1010,"humidity":69,"temp_min":296.15,"temp_max":298.15},"visibility":16093,"wind":{"speed":5.7,"deg":150,"gust":11.8},"clouds":{"all":90},"dt":1519082640,"sys":{"type":1,"id":2558,"message":0.0053,"country":"US","sunrise":1519045581,"sunset":1519086201},"id":4671654,"name":"Austin","cod":200}

The specifics are probably not important, it's just a pull from WeatherApi, but I can see that it works. 具体细节可能并不重要,这只是WeatherApi的优势,但我可以看到它的有效性。 Also, that it appears to be a string. 另外,它似乎是一个字符串。 Importantly if I try and println(d.toString()) it recognizes it as a string, and greys out .toString() 重要的是,如果我尝试使用println(d.toString())它将其识别为字符串,并且将.toString() println(d.toString())

Now, from the Klaxon parsing I get the following error: 现在,从Klaxon解析中,我得到以下错误:

FATAL EXCEPTION: main
 Process: com.example.patientplatypus.androidhoneytabs, PID: 32050
 java.lang.ClassCastException: com.beust.klaxon.JsonArray cannot be cast to java.lang.String
    at com.beust.klaxon.JsonObject.string(JsonObject.kt:74)
        at com.example.patientplatypus.androidhoneytabs.MainActivity$onCreate$2.invoke(MainActivity.kt:74)
        at com.example.patientplatypus.androidhoneytabs.MainActivity$onCreate$2.invoke(MainActivity.kt:39)
        at com.github.kittinunf.fuel.core.DeserializableKt$response$1.invoke(Deserializable.kt:37)
        at com.github.kittinunf.fuel.core.DeserializableKt$response$1.invoke(Unknown Source:4)
        at com.github.kittinunf.fuel.core.DeserializableKt$response$5$1.invoke(Deserializable.kt:62)
        at com.github.kittinunf.fuel.core.DeserializableKt$response$5$1.invoke(Unknown Source:0)
        at com.github.kittinunf.fuel.core.Request$callback$1.run(Request.kt:225)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

So the error here is telling me that somewhere I am trying to cast a jsonarray object to a string. 所以这里的错误告诉我,我正在某处尝试将jsonarray对象转换为字符串。 It can't be from d -> JsonObject. 它不能来自d-> JsonObject。 I have seen that if I comment out the line println("Weather : ${json.string("weather")}") , but I'm not sure if that still means that the val json object is still being mishandled (if it assigns and isn't used does the compiler properly evaluate it?). 我已经看到,如果我将println("Weather : ${json.string("weather")}")println("Weather : ${json.string("weather")}") ,但是我不确定这是否仍然意味着val json对象仍然被错误处理(如果它分配并且未使用,编译器是否会正确评估它?)。

What's frustrating is that this appears to be proper usage according to the Klaxon documentation. 令人沮丧的是,根据Klaxon文档,这似乎是正确的用法。 See: https://github.com/cbeust/klaxon and below: 参见: https : //github.com/cbeust/klaxon及以下:

val parser: Parser = Parser()
val stringBuilder: StringBuilder = StringBuilder("{\"name\":\"Cedric Beust\", \"age\":23}")
val json: JsonObject = parser.parse(stringBuilder) as JsonObject
println("Name : ${json.string("name")}, Age : ${json.int("age")}")

Does anyone have any ideas what is going wrong? 有谁知道出什么问题了吗?

Quick Edit: 快速编辑:

 result.fold({ d ->
        println("value of d")
        println(d)
        val parser: Parser = Parser()
        val stringBuilder: StringBuilder = StringBuilder("{\"name\":\"Cedric Beust\", \"age\":23}")
        val json: JsonObject = parser.parse(stringBuilder) as JsonObject
        println("Name : ${json.string("name")}, Age : ${json.int("age")}")

Does correctly print Cedric's name. 正确打印Cedric的名称。 So that seems fine. 因此,这似乎很好。 Hmm.... 嗯...

Neat, that I know Fuel. 整洁,我知道加油。

"http://api.openweathermap.org/data/2.5/weather?q=Austin,us&appid=MYAPIKEYSUPERDUPERSECRET"
        .httpGet().responseJSON { _, _, result ->
    result.get().obj() // here you have your JSON object
}

Note , that httpGet is just another way of writing Fuel.get() , it is a String extension function and the important part is that I used reponseJSON instead of responseString . 请注意httpGet只是编写Fuel.get()另一种方法,它是String扩展函数,重要的部分是我使用了reponseJSON而不是responseString Also you will need to use .getString("name") on the object. 另外,您将需要在对象上使用.getString("name") You can also use something like .getJSONObject or .getJSONArray . 您还可以使用.getJSONObject.getJSONArray类的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM