skip to Main Content

Is it possible to somehow convert a dynamic JSON object (No fixed schema) into a Java object?

For example, for first time, I can get the following JSON object at runtime:

{
  "addressDetails": {
    "homeAddresses": [
      {
        "houseNo": "1",
        "city": "2"
      }
    ],
    "currentAddress": {
      "houseNo": "1",
      "city": "2"
    }
  },
  "personalDetails": {
    "birthDetails": {
      "birthPlace": "1",
      "birthMonth": "2"
    }
  },
  "confidentialDetails": {
    "birthDetails": {
      "birthPlace": "1",
      "birthMonth": "2"
    }
  },
  "bankingDetails": {
    "bankName": "1",
    "bankAccountNo": 2
  }
}

The next time, maybe with something like this:

{
  "confidentialDetails": {
    "birthDetails": {
      "birthPlace": "1",
      "birthMonth": "2"
    }
  },
  "personalDetails": {
    "birthDetails": {
      "birthPlace": "1",
      "birthMonth": "2"
    }
  }
}

How can I handle all these variations? Is it possible with Jackson/Gson or some other library?

I expect to find a solution which is very generic and can handle the different variations in JSON object gracefully.

3

Answers


  1. You can deserialize it into Map<String,Object>

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper(); // This is an expensive operation. objectMapper is thread-safe so it cane be shared
        String inboundJsonStr = "{"name":"Jane Doe","id":2,"is_active":null}";
        Map<String,Object> jsonObject = objectMapper.readValue(inboundJsonStr, Map.class);
    }
    

    ObjectMapper is from Jackson library

    sidenote: Java is a typed language. If you do this, you will loose some benefits of the type check that language offers

    Login or Signup to reply.
  2. I don’t know if I understand your question. However, you can try to define all possible JSON objects into one object and then serialize them using GSON or another JSON conversion tool.
    like this:

    public class Parent {
        private AddressDetails addressDetails;
        private PersonalDetails personalDetails;
        private PersonalDetails confidentialDetails;
    }
    class AddressDetails{
        private List<HomeAddresses> homeAddresses;
        private List<CurrentAddress> currentAddresses;
    }
    class Addresses{
        private String houseNo;
        private String city;
    }
    class BirthDetails{
        private String birthDetails;
        private String birthMonth;
    }
    class HomeAddresses extends Addresses{
    }
    class CurrentAddress extends Addresses{
    }
    class PersonalDetails extends BirthDetails{
    }
    

    Or if there are too many types to define, you can simply convert the JSON string to a JSON object for use
    like this:

    String jsonStr = "{n" +
                "  "addressDetails": {n" +
                "    "homeAddresses": [n" +
                "      {n" +
                "        "houseNo": "1",n" +
                "        "city": "2"n" +
                "      }n" +
                "    ],n" +
                "    "currentAddress": {n" +
                "      "houseNo": "1",n" +
                "      "city": "2"n" +
                "    }n" +
                "  },n" +
                "  "personalDetails": {n" +
                "    "birthDetails": {n" +
                "      "birthPlace": "1",n" +
                "      "birthMonth": "2"n" +
                "    }n" +
                "  },n" +
                "  "confidentialDetails": {n" +
                "    "birthDetails": {n" +
                "      "birthPlace": "1",n" +
                "      "birthMonth": "2"n" +
                "    }n" +
                "  },n" +
                "  "bankingDetails": {n" +
                "    "bankName": "1",n" +
                "    "bankAccountNo": 2n" +
                "  }n" +
                "}";
        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
        JSONObject addressDetails = jsonObject.get("addressDetails", JSONObject.class);
        JSONArray homeAddresses = addressDetails.get("homeAddresses", JSONArray.class);
        JSONObject object = homeAddresses.get(0, JSONObject.class);
        System.out.println(object.get("houseNo"));
        System.out.println(object.get("city"));
    
    Login or Signup to reply.
  3. It is possible to do that with Jackson library. Just read the JSON and remove data with addressDetails and bankingDetails keys.

    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.databind.node.ObjectNode;
    import java.io.IOException;
    
    public class JavaApplication {
    
        public static void main(String[] args) throws IOException {
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
    
            ObjectNode jsonData = (ObjectNode) mapper.readTree("{"addressDetails":{"homeAddresses":[{"houseNo":"1","city":"2"}],"currentAddress":{"houseNo":"1","city":"2"}},"personalDetails":{"birthDetails":{"birthPlace":"1","birthMonth":"2"}},"confidentialDetails":{"birthDetails":{"birthPlace":"1","birthMonth":"2"}},"bankingDetails":{"bankName":"1","bankAccountNo":2}}");
            jsonData.remove("addressDetails");
            jsonData.remove("bankingDetails");
            System.out.println(mapper.writeValueAsString(jsonData));
        }
    }
    

    The output will be:

    {
      "personalDetails" : {
        "birthDetails" : {
          "birthPlace" : "1",
          "birthMonth" : "2"
        }
      },
      "confidentialDetails" : {
        "birthDetails" : {
          "birthPlace" : "1",
          "birthMonth" : "2"
        }
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search