Prosta aplikacja w javafx (2) - czytamy dane z pliku
Prototyp aplikacji działający na statycznych, “zhardkodowanych” danych (nasz HamdmadeService
oferuje gotowe Javowe obiekty), wydaje się działać. Jednak prawdziwe dane istnieją formacie JSON. Spróbujmy więc wczytać (i wyświetlić) dane w tym formacie.
Czytanie danych z pliku
Na razie jeszcze nie będziemy się jeszcze łączyć z internetem. Będziemy czytać dane z plików:
- lista krajów będzie odczytywana z pliku covidstat/src/main/resources/countries.json
- dane dla kraju będą odczytywane z pliku
<slug>
.json, gdzie<slug>
to pole “slug” z obiektu opisującego kraj w pliku countries.json, na przykład: - dla Polski plik będzie w covidstat/src/main/resources/poland.json
- dla Niemiec plik będzie w covidstat/src/main/resources/germany.json
Dla uproszczenia, na liście krajów umieściłam tylko Polskę i Niemcy, i ściągnęłam dane szczegółowe również tylko dla tych krajów.
Stworzę nową implementację interfejsu CovidService
o oryginalnej nazwie FileService
, która:
- odczyta odpowiednie pliki w katalogu resources
- zdeserializuje je do rekordów
Country
iCase
Parsowanie JSON-a
Wybór biblioteki
Użyję biblioteki, która jest de-facto standardem w zakresie (de)serializacji jsona, czyli fasterxml i założę, że wszystko pójdzie jak z płatka.
Dodaję do pom.xml najświeższy jackson-databind:
|
|
i “wymagam” pakietu w module-info.java:
|
|
Ponieważ nie do końca jestem pewna, jak jackson poradzi sobie z deserializacją do rekordów, wygooglowuję informację o wspieraniu rekordów i na wszelki wypadek wskazuję pola rekordu jako @JsonProperty:
|
|
Czy to wystarczy?
Eksport modułu z rekordami do Jacksona
Próba uruchomienia kończy się wyjątkiem:
|
|
Świetny opis błędu - wiem, co robić; dodaję jeszcze jeden wiersz do module-info.java:
|
|
A po próbie uruchomienia i błędzie:
|
|
dodaję kolejny:
|
|
Lista krajów deserializuje się poprawnie.
Parsowanie obiektów Case
Nieznane właściwości
Problem z “nieznanymi” właściwościami:
|
|
rozwiązuję wygooglowując tutorial na Jencov.com i dodając do kodu:
|
|
Parsowanie LocalDate oraz int
Kolejny problem to parsowanie obiektu Case
:
|
|
Decyduję się napisać własny deserializator do pól w klasie Case
. Tym bardziej, że pola w klasie Country to LocalDate oraz wartości int.
Wystarczy rzut oka na tutorial Baeldung i jedziemy!
Deserializator dla rekordu Case
Implementuję deserializator CaseDeserializer
:
|
|
Rejestracja deserializatora w mapperze
Teraz już tylko rejestruję CaseDeserializer
w moim mapperze w klasie FileService
:
|
|
Screenshot - wykres pełnego zakresu danych
Oto wykres wszystkich serii danych dla rzeczywistych danych ściągniętych ze źródła https://api.covid19api.com/
Repozytorium
Kod dostępny jest na GitHubie: covidstat.
Zmiany źródeł opisanie w tym wpisie zostały zawarte w komicie b87686d6f561.
Ten wpis jest częścią serii javafx-covid.