jsonkotlinmaxmind

Map JSON field values to data class values


I'm getting a JSON string that I'd like to clean up a bit and return less data. However, I'm having trouble figuring out how to get the values from the JSON and properly attach it to a data class I've created.

Here is the incoming JSON:

{
  "continent": {
    "code": "EU",
    "names": {
      "de": "Europa",
      "ru": "Европа",
      "pt-BR": "Europa",
      "ja": "ヨーロッパ",
      "en": "Europe",
      "fr": "Europe",
      "zh-CN": "欧洲",
      "es": "Europa"
    },
    "geoname_id": 6255148
  },
  "country": {
    "is_in_european_union": true,
    "names": {
      "de": "Frankreich",
      "ru": "Франция",
      "pt-BR": "França",
      "ja": "フランス共和国",
      "en": "France",
      "fr": "France",
      "zh-CN": "法国",
      "es": "Francia"
    },
    "iso_code": "FR",
    "geoname_id": 3017382
  },
  "city": {
    "geoname_id": 2977058,
    "names": {
      "en": "Saint-Saulve",
      "ru": "Сен-Сольв",
      "zh-CN": "圣索尔沃"
    }
  },
  "location": {
    "accuracy_radius": 10,
    "time_zone": "Europe/Paris",
    "latitude": 50.3714,
    "longitude": 3.5561
  },
  "postal": {
    "code": "59880"
  },
  "registered_country": {
    "is_in_european_union": true,
    "names": {
      "de": "Frankreich",
      "ru": "Франция",
      "pt-BR": "França",
      "ja": "フランス共和国",
      "en": "France",
      "fr": "France",
      "zh-CN": "法国",
      "es": "Francia"
    },
    "iso_code": "FR",
    "geoname_id": 3017382
  },
  "subdivisions": [
    {
      "names": {
        "fr": "Hauts-de-France",
        "en": "Hauts-de-France"
      },
      "iso_code": "HDF",
      "geoname_id": 11071624
    },
    {
      "names": {
        "de": "Nord",
        "en": "North",
        "fr": "Nord",
        "es": "Norte"
      },
      "iso_code": "59",
      "geoname_id": 2990129
    }
  ]
}

Data Classes:

data class locationData(val accuracyRadius: String = "", val timeZone: String = "", val latitude: String = "",
                        val longitude: String = "", val postalCode: String = "", val continent: Continent,
                        val country: Country, val city: City, val subdivision: Subdivision)
data class Continent(val code: String = "", val name: String = "", val geonameId: String = "")
data class Country(val isEU: Boolean = false, val name: String = "", val isoCode: String = "", val geonameId: String = "")
data class City(val name: String = "", val geonameId: String = "")
data class Subdivision(val name: String = "", val isoCode: String = "", val geonameId: String = "")

My sad attempt at iterating through the json and filtering out the pieces I don't want:

private fun cleanData(data: JsonNode): String {
    data.fieldNames().forEachRemaining { field -> 
        println(field);
    }

    val result = data.filter { item ->
        if (item.has("names")) {
            return item.get("names").has("en"); item["name"] = item.get("names").get("en");
        }
        return item.toString();
    }

    return "";

    /*val continent = {
        "code" = data.get("continent").get("code"),

    }*/
}

This is what my desired JSON output should be:

{   
    "accuracy_radius": 10,
    "time_zone": "Europe/Paris",
    "latitude": 50.3714,
    "longitude": 3.5561,
    "postalCode": "59880",
    "continent": {
        "code": "EU",
        "name": "Europe",
        "geonameId": 6255148
    },
    "country": {
        "isEU": true,
        "name": "France",
        "isoCode": "FR",
        "geonameId": 3017382
    },
    "city": {
        "geonameId": 2977058,
        "name": "Saint-Saulve",
    },
    "subdivisions": [
        {
          "name": "Hauts-de-France"
          "isoCode": "HDF",
          "geonameId": 11071624
        },
        {
          "name": "North",
          "isoCode": "59",
          "geonameId": 2990129
        }
    ]
}

Solution

  • I would suggest using Moshi (https://github.com/square/moshi/) and a custom adapter (see the examples on the github page) to filter/transform your data, when you read them into your data classes. If you have properly filled data objects, you should be able to write your desired JSON without any problems.