0

I am doing an API call with certain parameters. The body of the Request is something like this:

{
  "billing": {
    "firstname": "John",
    "lastname": "Master",
    "email": "abc.com"
  },
  "address": {
    "firstname": "John",
    "lastname": "Master",
    "email": "abc.com",
    "telephone": "+919999999999"
  },
  "payments": [
    {
      "code": "abcd",
      "amount": 500
    }
  ],
  "refno": "abcd123",
  "successUrl": "https://baseurl/ordercomplete/success",
  "failureUrl": "https://baseurl/ordercomplete/failure",
  "products": [
    {
      "sku": "sampleSKU",
      "price": 500,
      "qty": 1,
      "currency": 356,
      "giftMessage": "",
      "theme": ""
    }
  ],
  "syncOnly": true,
  "deliveryMode": "API"
}

I want to sort the parameters of the request alphabetically. The sorting should be done at outer level and inner level as well. For example, address should come before billing after the sort. Within the internal JSON also I want it to be sorted. For example in the billing struct email should come before lastname.

So the answer that I am looking for is:

{
    "address": {
    "firstname": "John",
    "lastname": "Master",
    "email": "abc.com",
    "telephone": "+919999999999"
  },
  "billing": {
    "firstname": "John",
    "lastname": "Master",
    "email": "abc.com"
  },
  "deliveryMode": "API",
  "failureUrl": "https://baseurl/ordercomplete/failure",
  "payments": [
    {
      "code": "abcd",
      "amount": 500
    }
  ],
  "products": [
    {
      "sku": "sampleSKU",
      "price": 500,
      "qty": 1,
      "currency": 356,
      "giftMessage": "",
      "theme": ""
    }
  ],
  "refno": "abcd123",
  "successUrl": "https://baseurl/ordercomplete/success",
  "syncOnly": true
}

I think I can do this by creating multiple POJO class having all the field and then implement a comparator which will sort it alphabetically. But this way of doing will make it very difficult even if a single field in the parameter of the request body change.

So I was thinking can we do it some better way where we do not have to worry about the field structure.

Ajay Kr Choudhary
  • 1,304
  • 1
  • 14
  • 23
  • I feel like this is an XY problem. The JSON is a dictionary, and dictionaries have no intrinsic order. So your desired answer and the original JSON are the _same_ JSON as far as JSON is concerned. Why do you want this? – Sweeper Aug 07 '20 at 10:53
  • I agree to you. But, there is one method that takes the input as the above request body and computes the HASH of that string. In that, the order of elements would matter and hence I need to convert into sorted order. – Ajay Kr Choudhary Aug 07 '20 at 10:56
  • Ah, that's some important info that you should [edit] into your question. Regardless, I think this is a bad design. If you can change the design, consider computing the hash from a parsed JSON object instead. – Sweeper Aug 07 '20 at 10:58
  • @Sweeper The API that I am calling is some third party API. It is not owned by me. Unfortunately, it is not something that I can control. – Ajay Kr Choudhary Aug 07 '20 at 11:01
  • According to [here](https://stackoverflow.com/questions/30030601/how-to-create-json-sorted-on-keys-using-gson), which might be a duplicate, you need to deserialise it to a sorted map first. But at that point, why not just compute the hash of the map? – Sweeper Aug 07 '20 at 11:01
  • 1
    Refer to this link. It will helpful for you to sort JSON. `https://www.stubbornjava.com/posts/creating-a-somewhat-deterministic-jackson-objectmapper#sort-the-keys` – Yabaze Cool Aug 07 '20 at 11:06
  • @Sweeper Looks like you have closed the question. although the links which you have pointed to is useful but it does not answer my question completely. I have done the enough research before posting this question. When I was not able to do it I asked it here. Simply closing the question without seeing all the detail is not good in my opinion. – Ajay Kr Choudhary Aug 07 '20 at 11:13
  • @Sweeper The link does not talk about sorting at both the inner and outer levels of JSON directly. I will have to do it manually in a recursive way. – Ajay Kr Choudhary Aug 07 '20 at 12:06

1 Answers1

1

You could use Jackson ObjectMapper and configure ObjectMapper as

om.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

Hope it was useful.

Sagar Saud
  • 124
  • 2
  • 11