Witam. Dopiero się uczę i mam problem z przerobieniem Json na liste obiektów. Piszę appkę gdzie otrzymuje od API z prognozą pogody następujący Json:
{
"data": [
{
"moonrise_ts": 1572876192,
"wind_cdir": "SE",
"rh": 84,
"pres": 982.153,
"high_temp": 9.3,
"sunset_ts": 1572884637,
"ozone": 322.467,
"moon_phase": 0.552016,
"wind_gust_spd": 6.28386,
"snow_depth": 0,
"clouds": 77,
"ts": 1572825660,
"sunrise_ts": 1572850839,
"app_min_temp": 8.1,
"wind_spd": 1.39257,
"pop": 40,
"wind_cdir_full": "southeast",
"slp": 985.03,
"valid_date": "2019-11-04",
"app_max_temp": 12.5,
"vis": 0,
"dewpt": 7.7,
"snow": 0,
"uv": 0.697746,
"weather": {
"icon": "c04d",
"code": 804,
"description": "Overcast clouds"
},
"wind_dir": 134,
"max_dhi": null,
"clouds_hi": 0,
"precip": 0.705078,
"low_temp": 8.1,
"max_temp": 12.5,
"moonset_ts": 1572907595,
"datetime": "2019-11-04",
"temp": 10.3,
"min_temp": 8.1,
"clouds_mid": 45,
"clouds_low": 54
},
{
"moonrise_ts": 1572964153,
"wind_cdir": "SW",
"rh": 86,
"pres": 993.705,
"high_temp": 12.4,
"sunset_ts": 1572970931,
"ozone": 323.897,
"moon_phase": 0.648931,
"wind_gust_spd": 10.783,
"snow_depth": 0,
"clouds": 91,
"ts": 1572912060,
"sunrise_ts": 1572937349,
"app_min_temp": 8,
"wind_spd": 2.9909,
"pop": 30,
"wind_cdir_full": "southwest",
"slp": 996.693,
"valid_date": "2019-11-05",
"app_max_temp": 12.4,
"vis": 0,
"dewpt": 7.5,
"snow": 0,
"uv": 1.5811,
"weather": {
"icon": "c04d",
"code": 804,
"description": "Overcast clouds"
},
"wind_dir": 226,
"max_dhi": null,
"clouds_hi": 4,
"precip": 0.427734,
"low_temp": 6,
"max_temp": 12.4,
"moonset_ts": 1572998028,
"datetime": "2019-11-05",
"temp": 9.6,
"min_temp": 8,
"clouds_mid": 41,
"clouds_low": 85
}
],
"city_name": "London",
"lon": "-0.09184",
"timezone": "Europe/London",
"lat": "51.51279",
"country_code": "GB",
"state_code": "ENG"
}
Jest to prognoza na dwa dni, gdzie każdy dzień jest jest elementem w tablicy "data" jednak tablica ta jest zagnieżdżona (Json nie zaczyna sie od [ ). Chciałbym aby każdy dzień był u mnie osobnym obiektem. Próbowałem różnych metod i bibliotek, ale najsensownieszy wydaje mi się własny deserializer. Mój wygląda tak:
public class WeatherDtoDeserializer extends JsonDeserializer<List<WeatherDto>> {
@Override
public List<WeatherDto> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode weatherNode = jp.getCodec().readTree(jp);
String city = weatherNode.get("city_Name").textValue();
List<WeatherDto> dtos = new ArrayList<>();
Iterator<JsonNode> itr = weatherNode.get("data").elements();
while (itr.hasNext()) {
JsonNode node = itr.next();
WeatherDto weatherDto = new WeatherDto();
weatherDto.setCity(city);
weatherDto.setDate(LocalDate.parse(node.get("valid_date").textValue()));
weatherDto.setTemperature(node.get("temp").intValue());
weatherDto.setCloudiness(node.get("clouds").intValue());
weatherDto.setRainfall(node.get("pop").intValue());
dtos.add(weatherDto);
}
return dtos;
}
}
Niestety kiedy próbuję do zrobić dostaję następujący błąd:
https://pastebin.com/bHs37XAP
Nie wiem co mam z tym zrobić. Prosiłbym o pomoc.
Jeszcze dodam klasą na którą chce przerobić json:
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@JsonDeserialize(using = WeatherDtoDeserializer.class)
public class WeatherDto {
private Long id;
private String city;
private LocalDate date;
private int temperature;
private int cloudiness;
private int rainfall;
public WeatherDto(String city, LocalDate date, int temperature, int cloudiness, int rainfall) {
this.city = city;
this.date = date;
this.temperature = temperature;
this.cloudiness = cloudiness;
this.rainfall = rainfall;
}
}
Oraz klient API pogody:
public List<WeatherDto> getForecast(Airport airport) {
URI url = UriComponentsBuilder.fromHttpUrl(getBaseUrl() +
"city=" + airport.getCity() +
"&country=" + airport.getCountryCode() +
"&key=" + KEY)
.build()
.encode()
.toUri();
String response = restTemplate.getForObject(url, String.class);
return Optional.ofNullable(restTemplate.getForObject(url, WeatherDto[].class))
.map(Arrays::asList)
.orElse(new ArrayList<>());
}