【问题标题】:How do I parse this Dynamic JSON value with Retrofit 2 and GSON?如何使用 Retrofit 2 和 GSON 解析这个动态 JSON 值?
【发布时间】:2020-06-19 19:23:20
【问题描述】:

我有这个嵌套的 JSON,我必须根据“sub_item”变量的内容来解析它,如果它是一个空字符串,它应该省略该变量,但如果它是一个 JsonObject(意味着它有子项)它应该相应地解析它们。

这是 JSON:

{
   "code":1,
   "msg":"OK",
   "details":{
      "validation_msg":"",
      "cart":{
         "cart":[
            {
               "item_id":"4417",
               "ingredients":"",
               "category_id":"600",
               "sub_item":{
                  "EXTRAS":[
                     {
                        "subcat_id":329,
                        "sub_item_id":"1683",
                        "total":147,
                        "sub_item_name":"Pork"
                     },
                     {
                        "subcat_id":329,
                        "sub_item_id":"1683",
                        "total":147,
                        "sub_item_name":"Pork"
                     }
                  ],
                  "SODAS":[
                     {
                        "subcat_id":329,
                        "sub_item_id":"1683",
                        "total":147,
                        "sub_item_name":"Coke"
                     },
                     {
                        "subcat_id":329,
                        "sub_item_id":"1683",
                        "total":147,
                        "sub_item_name":"Pepsi"
                     }
                  ]
               }
            }
         ]
      },
      "has_pts":1
   }
}

这是我在 Retrofit 中使用的 POJO:

data class ResumenTotalDelCarritoWrapper(
    @SerializedName("code")
    var code: Int,
    @SerializedName("details")
    var details: Details,
    @SerializedName("msg")
    var msg: String
) {
    data class Details(
        @SerializedName("cart")
        var cart: Cart,
        @SerializedName("estimation_delivery_time")
        var estimationDeliveryTime: String

    ) {
        data class Cart(
            @SerializedName("cart")
            var cartItems: ArrayList<CartItem> = ArrayList()
        ) {

            data class CartItem(
                @SerializedName("category_id")
                var categoryId: String,
                @SerializedName("ingredients")
                var ingredients: JsonElement,
                @SerializedName("item_id")
                var itemId: String,
                @SerializedName("sub_item")
                var subItems: JsonElement
            )

            data class subItem(
                @SerializedName("sub_item_id")
                var subItemId: String,
                @SerializedName("sub_item_name")
                var subItemName: String,
                @SerializedName("subcat_id")
                var subcatId: Int,
                @SerializedName("total")
                var total: Int
            )

        }
    }
}

这里是改造电话:

     fun APIcall2() {

        val call = RetrofitClient.getInstance("ListaDeRestaurantes").getApi()
            .loadCart(
                "payment_option",
                "delivery",
                MainActivity2.getLoginToken().trim(),
                "undefined",
                "",
                MainActivity2.pedidoCarrito!!.deliveryInstruction,
                MainActivity2.pedidoCarrito!!.merchantID,
                MainActivity2.pedidoCarrito!!.formattedAddress,
                MainActivity2.pedidoCarrito!!.street,
                MainActivity2.pedidoCarrito!!.cityName,
                MainActivity2.pedidoCarrito!!.cityName,
                MainActivity2.pedidoCarrito!!.cityID,
                MainActivity2.pedidoCarrito!!.state,
                MainActivity2.pedidoCarrito!!.stateID,
                MainActivity2.pedidoCarrito!!.cityID,
                MainActivity2.pedidoCarrito!!.areaName,
                MainActivity2.pedidoCarrito!!.areaID,
                MainActivity2.pedidoCarrito!!.areaID,
                MainActivity2.pedidoCarrito!!.deliveryTime,
                MainActivity2.pedidoCarrito!!.deliveryDate,
                MainActivity2.pedidoCarrito!!.carritoURLSTring,
                "0",
                MainActivity2.pedidoCarrito!!.phoneNumber
            )


        call.enqueue(object : Callback<ResumenTotalDelCarritoWrapper> {
            override fun onResponse(
                call: retrofit2.Call<ResumenTotalDelCarritoWrapper>,
                response: Response<ResumenTotalDelCarritoWrapper>
            ) {
                val defaultResponse = response.body()

                if (defaultResponse?.code == 1) {

                    for (cartItem in defaultResponse.details.cart.cartItems) {

                        if (cartItem.subItems is JsonObject) {

                            var jsonObject: JsonObject = cartItem.subItems as JsonObject

                            val gson3 = GsonBuilder().create()
                            var map: Map<String, ArrayList<ResumenTotalDelCarritoWrapper.Details.Cart.subItem>> =
                                HashMap()
                            map = gson3.fromJson(jsonObject, map.javaClass)

                            //This is an Array of the category names of the list of Sub-Items
                            val listaDeSubitemsKeyTitle: ArrayList<String>? = ArrayList()

                            //This is an Array of Arrays of Sub-Items
                            val listaDeSubitemsValue: ArrayList<ArrayList<ResumenTotalDelCarritoWrapper.Details.Cart.subItem>> = ArrayList()

                            map.forEach { (key, value) ->
                                listaDeSubitemsKeyTitle!!.add(key)
                                listaDeSubitemsValue!!.add(value)
                            }

                            for (subItemList in listaDeSubitemsValue) {

                            /* This next loops throws the following error:
                                java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap 
                                cannot be cast to com.asiderapido.deliveryapp.Models.ResumenTotalDelCarritoWrapper$Details$Cart$subItem
                            */
                                for (subitem in subItemList) {

                                //This should  log the name of each sub item
                                    Log.e("Resumen carrito","Subitem category name: " + subitem.subItemName)
                                }
                            }
                        }
                    }

                } else {

                    //Log.e(LOG_TAG, "PedidosCompletadosFragment else");
                }
            }

            override fun onFailure(call: Call<ResumenTotalDelCarritoWrapper>, t: Throwable) {
                t.printStackTrace()
            }
        })
    }
}

之前的APICall函数抛出这个错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 14512
    java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.asiderapido.deliveryapp.Models.ResumenTotalDelCarritoWrapper$Details$Cart$subItem
        at com.asiderapido.deliveryapp.ui.carrito.ResumenTotalDelCarrito$APIcall$1.onResponse(ResumenTotalDelCarrito.kt:211)

【问题讨论】:

    标签: android json kotlin gson retrofit2


    【解决方案1】:

    我解决了我的问题!

    下面是 Retrofit 调用:

     for (cartItem in defaultResponse.details.cart.cartItems) {
                       
                                if (cartItem.subItems is JsonObject) {
    
                                    cartItem!!.subItemLists
    
                                    var jsonObject: JsonObject = cartItem.subItems as JsonObject
    
                                    val gson3 = GsonBuilder().create()
                                    var map: Map<String, ArrayList<JsonElement>> =
                                        HashMap()
                                    map = gson3.fromJson(jsonObject, map.javaClass)
    
    
                                    val listaDeSubitemsKeyTitle: ArrayList<String>? = ArrayList()
    
                                    val listaDeSubitemsValue: ArrayList<ArrayList<JsonElement>> = ArrayList()
    
                                    map.forEach { (key, value) ->
    
                                        listaDeSubitemsKeyTitle!!.add(key)
                                        listaDeSubitemsValue!!.add(value)
    
                                    }
    
                                    for (subItemList in listaDeSubitemsValue) {
    
                                        var gson =  GsonBuilder().create();
                                        var  myCustomArray: JsonArray = gson.toJsonTree(subItemList).getAsJsonArray();
    
                                        val gson7 = GsonBuilder().create()
                                        val type = object : TypeToken<List<ResumenTotalDelCarritoWrapper.Details.Cart.subItem>>() {}.type
                                        var subItemList = gson7.fromJson<List<ResumenTotalDelCarritoWrapper.Details.Cart.subItem>>(myCustomArray, type)
    
                                        for (subitem
                                        in subItemList) {
    
                                           Log.e( "Cart Review", "Subitem category name: " + subitem.categoryName)
                                   
                                        }
                                    }
    
                                    listaDeSubitemsValue!!.get(0)
                                }
                          
                            }
    

    【讨论】:

      猜你喜欢
      • 2015-12-05
      • 1970-01-01
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 2015-06-15
      • 2021-01-07
      相关资源
      最近更新 更多