Como converter um Json Array to Json Object usando Gson

Tenho duas aplicações woocommerce e um sistema desenvolvido em spring boot.

Recebo na aplicação spring json atraves da requisição abaixo:

@GetMapping("saveOrderCopy/")
    public ResponseEntity<AjaxResponse> saveOrderCopy(@RequestBody Object params){
        AjaxResponse ajaxResponse = new AjaxResponse();

        WoocommerceOrder wooOrder = new WoocommerceOrder();
        wooOrder.setJsonOrderData(params.toString());

        System.out.println(wooOrder.getJsonOrderData());

        try {
            Gson gson = new Gson();
            JsonObject json = gson.toJsonTree(params).getAsJsonObject();
            wooOrder.setJsonOrderData(params.toString());

            long idOrder = Long.parseLong(json.get("id").toString());
            wooOrder.setIdOrder(idOrder);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return new ResponseEntity<AjaxResponse>(ajaxResponse, HttpStatus.OK);
    }

E o meu Json é:

{
   "id":3143,
   "parent_id":0,
   "status":"processing",
   "currency":"BRL",
   "version":"6.7.0",
   "prices_include_tax":false,
   "date_created":{
      "date":"2022-10-01 14:49:25.000000",
      "timezone_type":3,
      "timezone":"America/Sao_Paulo"
   },
   "date_modified":{
      "date":"2022-10-01 17:53:10.000000",
      "timezone_type":3,
      "timezone":"America/Sao_Paulo"
   },
   "discount_total":"0",
   "discount_tax":"0",
   "shipping_total":"16",
   "shipping_tax":"0",
   "cart_tax":"0",
   "total":"315.00",
   "total_tax":"0",
   "customer_id":1,
   "order_key":"wc_order_JqrCaVciPx0tf",
   "billing":{
      "first_name":"Gabriel",
      "last_name":"Filippi",
      "company":"Floricultura",
      "address_1":"r xv de novembro",
      "address_2":"floricultura filippi",
      "city":"joinville",
      "state":"SC",
      "postcode":"89237-000",
      "country":"BR",
      "email":"gabriel._gf@hotmail.com",
      "phone":"47991952764"
   },
   "shipping":{
      "first_name":"Margarida",
      "last_name":"Filippi",
      "company":"floricultura",
      "address_1":"rua sabia",
      "address_2":"casa",
      "city":"joinville",
      "state":"SC",
      "postcode":"89220-030",
      "country":"BR",
      "phone":""
   },
   "payment_method":"cheque",
   "payment_method_title":"Cheque",
   "transaction_id":"",
   "customer_ip_address":"::1",
   "customer_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
   "created_via":"checkout",
   "customer_note":"",
   "date_paid":{
      "date":"2022-10-01 14:51:09.000000",
      "timezone_type":3,
      "timezone":"America/Sao_Paulo"
   },
   "cart_hash":"6f7e0d599ae9463eb47ce1f48bf719e7",
   "number":"3143",
   "meta_data":[
      {
         "id":14957,
         "key":"_iconic_wds_is_same_day",
         "value":""
      },
      {
         "id":14958,
         "key":"_iconic_wds_is_next_day",
         "value":""
      },
      {
         "id":14959,
         "key":"jckwds_date",
         "value":"04/10/2022"
      },
      {
         "id":14960,
         "key":"jckwds_date_ymd",
         "value":"20221004"
      },
      {
         "id":14961,
         "key":"jckwds_timeslot",
         "value":"16:00 - 17:00"
      },
      {
         "id":14962,
         "key":"jckwds_timestamp",
         "value":"1664910000"
      },
      {
         "id":14964,
         "key":"is_vat_exempt",
         "value":"no"
      },
      {
         "id":14968,
         "key":"_new_order_email_sent",
         "value":"true"
      },
      {
         "id":14974,
         "key":"qr_code_to_confirm_order",
         "value":"http://localhost:8080/uploads/qrCodes/ecommerce/10-2022/01/3143/3143.png"
      },
      {
         "id":14975,
         "key":"dfiFeatured",
         "value":[
            ""
         ]
      }
   ],
   "line_items":{
      "5":{
         
      }
   },
   "tax_lines":[
      
   ],
   "shipping_lines":{
      "6":{
         
      }
   },
   "fee_lines":[
      
   ],
   "coupon_lines":[
      
   ]
}

Tudo funciona normal ao tentar acessar o id como faço no código abaixo, porém ao tentar acessar a key “meta_data” ela me retorna um array, gostaria de saber como posso tranformar para jsonObject esse array e assim poder acessar os keys que desejo.

Tentou a estratégia de percorrer esse array?

Bom dia Lucas! Ja pensei nisso, mas seria essa a melhor maneira? Fico com essa dúvida

Se o valor de meta_data é um array, basta obter o valor como um JsonArray e percorrê-lo:

JsonObject json = gson.toJsonTree(params).getAsJsonObject();

for (JsonElement element: json.getAsJsonArray("meta_data")) {
    JsonObject obj = element.getAsJsonObject();
    System.out.printf("id=%d, key=%s, value=%s\n", obj.get("id").getAsLong(), obj.get("key").getAsString(), obj.get("value").getAsString());
}

Repare que cada elemento do array é um objeto, então para cada um, você converte para JsonObject e aí pega as chaves que precisar.

Note também que para obter o valor como número não precisa de Long.parseLong, dá para usar o método getAsLong que já faz essa conversão para você (ou seja, para pegar o id poderia ser apenas json.get("id").getAsLong()).


De forma geral, não é difícil ler um JSON, basta ver bem o que cada estrutura representa. No seu caso, dentro de meta_data temos:

"meta_data":[
      {
         "id":14957,
         "key":"_iconic_wds_is_same_day",
         "value":""
      },
      {
         "id":14958,
         "key":"_iconic_wds_is_next_day",
         "value":""
      },
      ...
]

Ou seja, o valor de meta_data está delimitado por [ ], e portanto é um array. Em um array, os elementos são separados por vírgulas (ex: [ elemento1, elemento2, elemento3 ]).

No caso, cada elemento é um object (pois está delimitado por { }), que por sua vez possui as chaves “id”, “key” e “value”.

Então para verificar as chaves de cada objeto, basta pegar o valor de meta_data (que é um array) e fazer um loop por este array. Dentro do loop, cada elemento é um object, e para cada um você pega as chaves que precisa.

1 curtida

@hugokotsubo Agradeço pela ajuda, acabei desenvolvendo dessa maneira mesmo. O código final ficou desta maneira:

 @GetMapping("saveOrderCopy/")
    public ResponseEntity<AjaxResponse> saveOrderCopy(@RequestBody Map<Object, Object> params){
        AjaxResponse ajaxResponse = new AjaxResponse();
        WoocommerceOrder wooOrder = new WoocommerceOrder();

        try {
            Gson gson = new Gson();
            //convert order Data to Json Object
            JsonObject jsonOrderData = gson.toJsonTree(params.get("orderData")).getAsJsonObject();
            wooOrder.setJsonOrderData(jsonOrderData.toString());

            //convert order product data to Json Array
            JsonArray jsonArrayProduct = gson.toJsonTree(params.get("orderItems")).getAsJsonArray();
            wooOrder.setJsonProductData(jsonArrayProduct.toString());

            //verify if order is saved in database, to not duplicate.
            long idOrder = jsonOrderData.get("id").getAsLong();
            WoocommerceOrder wooSavedOrder = wooOrderService.findByOrderId(idOrder);
            if(wooSavedOrder !=null){
                wooOrder.setId(wooSavedOrder.getId());
            }
            wooOrder.setIdOrder(idOrder);

            /**
             * metadata key is array, to get values inside this array, we need to traverse the array for that we assemble a list of JsonElements
             **/
            ArrayList<JsonElement> listdata = new ArrayList<JsonElement>(); 
            JsonArray jsonArray = jsonOrderData.getAsJsonArray("meta_data");
            if (jsonArray != null) {   
                //Iterating JSON array  
                for (int i=0;i<jsonArray.size();i++){   
                    //Adding each element of JSON array into ArrayList  
                    listdata.add(jsonArray.get(i));  
                }   
            }  

            boolean getDeliveryTime = false; 
            boolean getDeliveryDate = false; 
            //Iterating ArrayList to print each element  
            for(int i=0; i<listdata.size(); i++) {  
                JsonElement element = listdata.get(i);

                JsonObject obj = element.getAsJsonObject();
                String key = obj.get("key").getAsString();
                String value = obj.get("value").getAsString();

                //save delivery date
                if(key.equals("jckwds_date")){
                    SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
                    Date deliveryDate = formatter.parse(value);
                    wooOrder.setDeliveryDate(deliveryDate);
                    getDeliveryDate = true; 
                }

                //save delivery time
                if(key.equals("jckwds_timeslot")){
                    wooOrder.setDeliveryTime(value);
                    getDeliveryTime = true; 
                }

                //if you have already saved the time and delivery date, we stop the loop
                if(getDeliveryTime && getDeliveryDate){
                    break;
                }
            }  

            wooOrderService.save(wooOrder);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new ResponseEntity<AjaxResponse>(ajaxResponse, HttpStatus.OK);
    }