I am reading a resource from a backend that is giving me an Map of entries. I am iterating these and retriving the values. The type of that value is object or object[], the actual types are common primitives or a Calender class.
My target is to create a json response, it should look like this:
{ "testUri": "https://www.google.de", "testDate": 1636986289929, "testLong": "123123", "testName": "name", "testPath": "path", "indexName": "AAA_de_de_offers", "testArrayDate": [1636986289929], "testArrayLong": [111, 222, 333], "testArrayUri": ["http://www.google.de", "http://www.test.de"], "testArrayDouble": [1.2, 2.1, 3.1], "testBoolean": "true", "testArrayBoolean": [true, true, false], "regex": "ASDASD", "suggestHeadline": "Beliebte Suchbegriffe", "testDecimal": "12", "testArrayDecimal": [1, 2, 3], "testDouble": "12.87", "testString": "testString" }
But I am really unhappy with the result, since I am repeating a lot of checks and methods that are doing the same , the only thing that differs is are the types.
The first step I am doing is to check which class I am facing
Object value = e.getValue(); final boolean valIsDate = value instanceof Calendar; final boolean valIsDateArray = Calendar[].class.equals(value.getClass()); final boolean valIsDouble = Double.class.equals(value.getClass()); final boolean valIsDoubleArray = Double[].class.equals(value.getClass()); final boolean valIsLong = Long.class.equals(value.getClass()); final boolean valIsLongArray = Long[].class.equals(value.getClass()); final boolean valIsBoolean = Boolean.class.equals(value.getClass()); final boolean valIsBooleanArray = Boolean[].class.equals(value.getClass()); final boolean valIsBigDecimal = BigDecimal.class.equals(value.getClass()); final boolean valIsBigDecimalArray = BigDecimal[].class.equals(value.getClass()); final boolean valIsString = value instanceof String; final boolean valIsStringArray = String[].class.equals(value.getClass());
After that I am creating the json entries with the help of a big if clause
JsonObject json = new JsonObject(); if (valIsStringArray) { json.add(key, getJsonArray((String[]) value)); } else if (valIsDate) { json.addProperty(key, ((Calendar) value).getTimeInMillis()); } else if (valIsDateArray) { json.add(key, getJsonArray((Calendar[]) value)); } else if (valIsDouble) { json.addProperty(key, (Double) value); } else if (valIsDoubleArray) { json.add(key, getJsonArray((Double[]) value)); } else if (valIsLong) { json.addProperty(key, (Long) value); } else if (valIsLongArray) { json.add(key, getJsonArray((Long[]) value)); } else if (valIsBoolean) { json.addProperty(key, (Boolean) value); } else if (valIsBooleanArray) { json.add(key, getJsonArray((Boolean[]) value)); } else if (valIsBigDecimal) { json.addProperty(key, gson.toJson(value, BigDecimal.class)); } else if (valIsBigDecimalArray) { json.add(key, getJsonArray((BigDecimal[]) value)); } else { // String is the default fallback json.addProperty(key, valueAsString); }
getJsonArray is receiving the array types and creating JsonArray entries for example
protected JsonArray getJsonArray(final Calendar[] arrayAsObject) { final JsonArray jsonArray = new JsonArray(); for (final Calendar e : arrayAsObject) { jsonArray.add(e.getTimeInMillis()); } return jsonArray; }
Im sure theres a better way to achieve this 🙂
Advertisement
Answer
You can use toJsonTree
method that recognizes automatically the object class.
json.add(key, new Gson().toJsonTree(value));