【问题标题】:JSON parsing using Gson returns an error for a boolean value使用 Gson 解析 JSON 返回布尔值的错误
【发布时间】:2019-07-27 05:10:20
【问题描述】:

我有以下从 WordPress 帖子生成的 json:

    {  
   "events":[  
      {  
         "id":4651,
         "title":"Test title",
         "description":"testttt",
         "image": {
            url: "https://myhost.tv/wp-content/uploads/2019/07/event2.jpg",
            id: "4652"}
       }
       ]
 }

我的json模型如下:

    data class EventsFeed(val events: Array<Events>)

    data class Events (

        val id : Int,
        val title : String,
        val description : String,
        val image : Image
    )


    data class Image (
        val url : String,
        val id : Int,
    )

我使用 Json 进行解析,一切正常,但是当我在 wordpress 中进行 POST 并且我没有放置图像时,Image 键的值将我设置为false,如下所示:

{  
   "events":[  
      {  
         "id":4651,
         "title":"Stand Up Comedy",
         "description":"testttt",
         "image":false
       }
       ]
 }

因为image 的值是false,所以解析会返回错误:Expected BEGIN_OBJECT but was BOOLEAN at line 1 column 5781 path $ .events [1] .image

当帖子没有图像可以正确解析时忽略false 的值,或者无论如何如果它是false,我该怎么做,请将其保留为默认图像 (https://myhost.com/image_defaul.jpg)

json 由 Wordpress 插件生成:活动日历:Demo json here

我的解析函数(使用Volley和Gson)如下(将数据数组发送到适配器以在recyclerview中显示)

fun jsonObjectRequest() {
    Log.i(LOG_TAG, "jsonObjectRequest")

    // Instantiate the RequestQueue.
    val queue = Volley.newRequestQueue(activity)

    val url = "https://myhost.tv/wp-json/tribe/events/v1/events"

    // Request a JSONObject response from the provided URL.
    val jsonObjectRequest = JsonObjectRequest( url, null,
        Response.Listener { response ->
            Log.i(LOG_TAG, "Response is: $response")

            val gson = Gson()
            val homeEvents  = gson.fromJson(response.toString(), EventsFeed::class.java)

            activity?.runOnUiThread {
                recyclerEvents.adapter = AdaptadorEventos(homeEvents)

            }   
        },
        Response.ErrorListener { error ->
            error.printStackTrace()
            Log.e(LOG_TAG, "That didn't work!")
        }
    )

    // Add the request to the RequestQueue.
    queue.add(jsonObjectRequest)
}

【问题讨论】:

  • 首先,您应该更改服务器响应,以便在没有图像时将图像字段设置为空。第二种解决方案是您必须手动解析 jsonparser 的响应。

标签: android json kotlin gson


【解决方案1】:

您的 post 方法没有获取 Image Class 对象的原因是因为 json 不是有效的 json,您可以在 https://jsonlint.com/ 上验证它。原因是:"url""id" 键没有被“”包围。看看下面的解决方案,效果很好:

package com.example.myapplication

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import com.google.gson.Gson

class MainActivity : AppCompatActivity() {

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

        getEvemtsObject()

    }

    private val jsonString = " {\n" +
            " \t\"events\": [{\n" +
            " \t\t\"id\": 4651,\n" +
            " \t\t\"title\": \"Test title\",\n" +
            " \t\t\"description\": \"testttt\",\n" +
            " \t\t\"image\": {\n" +
            " \t\t\t\"url\": \"https://myhost.tv/wp-content/uploads/2019/07/event2.jpg\",\n" +
            " \t\t\t\"id\": \"4652\"\n" +
            " \t\t}\n" +
            " \t}]\n" +
            " }"

    private fun getEvemtsObject() {
        val gson = Gson()
        System.out.println("from_gson  ---> " + gson.fromJson<EventsFeed>(jsonString,EventsFeed::class.java))
    }

}

【讨论】:

  • json 由 Wordpress 的插件生成:事件日历:Demo wpshindig.com/wp-json/tribe/events/v1/events。解析事件对我来说可以正常工作,当我创建一个事件并且我没有附加图像时,问题就出现了。
  • 使 Image 键可以为空。 “验证图像:图像?”因此,当您不附加图像时。要发送的默认值应该是“null”而不是“false”。
  • 在删除图像键后尝试解析。它对我来说很好...... private val jsonString1 = "{\n" + "\t\"events\": [{\n" + "\t\t\"id\": 4651,\n" + "\t\t\"title\": \"测试标题\",\n" + "\t\t\"description\": \"testttt\"\n" + "\t}]\n" + "}" 私有乐趣 getEvemtsObject() { val gson = Gson() System.out.println("from_gson ---> " + gson.fromJson(jsonString1, EventsFeed::class.java)) }跨度>
【解决方案2】:

您可以像这样使用自定义 Gson 反序列化器:

class EventsDeserializer : JsonDeserializer<Events> {
    override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Events {
        val jsonObject = json.asJsonObject
        return Events(
            id = jsonObject.get("id").asInt,
            title = jsonObject.get("title").asString,
            description = jsonObject.get("description").asString,
            image = parseImage(context, jsonObject.get("image"))
        )
    }

    private fun parseImage(context: JsonDeserializationContext, json: JsonElement): Image =
        try {
            context.deserialize(json, Image::class.java)
        } catch (_: Throwable) {
            Image("https://myhost.com/image_defaul.jpg", 0)
        }
}

这是对您的 json 的测试:

fun main() {
    val gson = GsonBuilder()
        .registerTypeAdapter(Events::class.java, EventsDeserializer())
        .create()
    val json = """
{
  "events": [
    {
      "id": 4651,
      "title": "Stand Up Comedy",
      "description": "testttt",
      "image": false
    }
  ]
}
    """.trimIndent()
    val events = gson.fromJson(json, EventsFeed::class.java)
}

【讨论】:

  • 我需要将它放在一个数组中以将其传递给recyclerview。
  • 是的,你有什么问题吗?
【解决方案3】:

构造函数中的图像参数应该可以为空。 像这样重写你的课程

data class Events (

    val id : Int,
    val title : String,
    val description : String,
    var image : Image? = null)

并更改您的 API 以发送 null 而不是 false

【讨论】:

    【解决方案4】:

    这也可能是一种选择(但修复 API 是更好的选择):

    val image: Any
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-12
      • 1970-01-01
      • 2016-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多