JavaTrip and tricks

Spring Boot #27 – Przetwarzanie danych z usługi REST bez modelu w kodzie

Spring Boot

Jednym z najczęściej wykorzystywanych sposobów by pobierać dane z usługi REST jest wykorzystanie klasy RestTemplate i przemapowanie JSON na POJO (klasy modelu).

W tym artykule pokażę jak w estetyczny sposób można operować na danych nie posiadając klas modelowych.

JsonNode

To klasa, która umożliwia na przechowywanie struktury drzewiastej obiektu JSON. Klasa ta pochodzi z pakietu com.fasterxml.jackson.databind – co oznacza, że znajduje się wewnątrz modułu Spring Web Starter i nie wymaga stosowania dodatkowych importów.

Przykład

Łączymy się z API, które ma następującą strukturę:

{
    "consolidated_weather": [
        {
            "id": 4591072749551616,
            "weather_state_name": "Heavy Cloud",
            "weather_state_abbr": "hc",
            "wind_direction_compass": "WNW",
            "created": "2019-07-25T19:10:58.841574Z",
            "applicable_date": "2019-07-25",
            "the_temp": 27.895,
        },
        {
            "id": 5466136332206080,
            "weather_state_name": "Light Rain",
            "weather_state_abbr": "lr",
            "wind_direction_compass": "NNE",
            "created": "2019-07-25T19:11:01.833177Z",
            "applicable_date": "2019-07-26",
            "the_temp": 24.035,
        }
    ],
    "time": "2019-07-25T23:54:43.732909+02:00",
    "sun_rise": "2019-07-25T04:45:36.568582+02:00",
    "sun_set": "2019-07-25T20:38:27.238865+02:00",
    "timezone_name": "LMT",
    "parent": {
        "title": "Poland",
        "location_type": "Country",
        "woeid": 23424923,
        "latt_long": "51.918919,19.134300"
    },
    "sources": [<->],
    "title": "Warsaw",
    "location_type": "City",
    "woeid": 523920,
    "latt_long": "52.235352,21.009390",
    "timezone": "Europe/Warsaw"
}

Jest ona wielokrotnie zagnieżdżona i w przypadku tworzenia modeli musielibyśmy stworzyć wiele klas modelowych. Natomiast jako alternatywne można wykorzystać JsonNode.

Łączymy się z API wykorzystując klasyczne podejście jakim jest RestTemplate. Jednak w metodzie getForObject podajemy, że typem do którego przekazujemy odpowiedź (Response type) jest JsonNode.class.

public void getData() {
    String url = "https://www.metaweather.com/api/location/523920/";
    RestTemplate restTemplate = new RestTemplate();

    JsonNode forObject = restTemplate.getForObject(url, JsonNode.class).get("consolidated_weather");
    for (JsonNode jsonNode : forObject) {
        System.out.println(jsonNode.get("weather_state_name") + " " + jsonNode.get("the_temp") + "°C");
    }
}

Z wykorzystaniem metody get tej klasy możemy otrzymać interesujący nas element na drzewie. W przypadku, kiedy zwracany element stanowi tablice to możemy się po niej przeliterować tak jak widać to w linii 6.

Możliwości

JsonNode może dać informacje czy element pobierany z wykorzystaniem metody get jest w rezultacie pojedynczym obiektem lub całą tablicą. Służą do tego metody:

  • isArray()
  • isObject()

Przed dokonaniem rzutowania można też wykorzystać szereg metod sprawdzających czy konwersja jest możliwa:

  • isInt()
  • isBigDecimal()
  • isDouble()
  • canConvertToInt()
  • canConvertToLong()

Wnioski

JsonNode umożliwia łatwe i przyjemne tworzenie klientów REST. Natomiast czy uciekanie od tworzenia modelu jest dobrą praktyka?

Zazwyczaj, kiedy zależy nam na pojedynczych polach – owszem. Ale kiedy dokonujemy operacji na wielokrotnie zagnieżdżonej strukturze to dobrze dla czytelności i łatwości utrzymania kodu jest wykorzsytać klasy modelowe.

Tags:
Show Buttons
Hide Buttons