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.
Zobacz listę szkoleń

