Skip to content
Advertisement

Serialize Object/Object[] entries to gson JsonObject

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));
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement