Как мне проанализировать это значение Dynami c JSON с помощью Retrofit 2 и GSON? - PullRequest
0 голосов
/ 19 июня 2020

У меня есть этот вложенный 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
   }
}

Вот POJO, который я использую с Retrofit:

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
            )

        }
    }
}

Вот вызов Retrofit:

     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)

1 Ответ

0 голосов
/ 26 июня 2020

Я решил свою проблему!

Вот вызов модернизации следующим образом:

 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)
                            }
                      
                        }
...