如何将对象节点的Json数组解析为不同的dto对象

时间:2019-11-04 19:27:56

标签: java arrays json

我从Weather api得到了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" }

这是预测的2天。我将使用16天,这样会更长。但是我想将其拆分,因此每天都是一个单独的对象,仅包含字段“ city_name”,“ valid_date”,“ temp”,“ clouds”和“ pop”。如何做到这一点,尤其是在数组嵌套且“ city_name”不在其内部时。我有以下反序列化类,该类显然不起作用:

public class WeatherDtoDeserializer extends StdDeserializer<WeatherDto> {

    public WeatherDtoDeserializer() {
        this(null);
    }

    public WeatherDtoDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public WeatherDto deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {

        JsonNode weatherNode = jp.getCodec().readTree(jp);
        WeatherDto weatherDto = new WeatherDto();
        weatherDto.setCity(weatherNode.get("city_Name").textValue());
        weatherDto.setDate(LocalDate.parse(weatherNode.get("data").get("valid_date").textValue()));
        weatherDto.setTemperature(weatherNode.get("data").get("temp").intValue());
        weatherDto.setCloudiness(weatherNode.get("data").get("clouds").intValue());
        weatherDto.setRainfall(weatherNode.get("data").get("pop").intValue());
        return weatherDto;
    }
}

这也是我在WeatherApiClient中获取预报的方法:

 public List<WeatherDto> getForecast(Airport airport) {
        URI url = UriComponentsBuilder.fromHttpUrl(getBaseUrl() +
                "city=" + airport.getCity() +
                "&country=" + airport.getCountryCode() +
                "&key=" + KEY)
                .build()
                .encode()
                .toUri();
        return Optional.ofNullable(restTemplate.getForObject(url, WeatherDto[].class))
                .map(Arrays::asList)
                .orElse(new ArrayList<>());
    }

在尝试获取预测并打印出来时出现错误: Error

谢谢。

1 个答案:

答案 0 :(得分:1)

我要说的最好的方法是先从city_Name获得JSON

String city = weatherNode.get("city_Name").textValue();

然后从data的{​​{1}}中获得JSON Array,并通过迭代每个Object节点将它们转换为Object nodes

WeatherDto

要返回List<WeatherDto> dtos = new ArrayList<>(); Iterator<JsonNode> itr = weatherNode.get("data").elements(); while(itr.hasNext()) { JsonNode node = its.next(); WeatherDto weatherDto = new WeatherDto(); // set all values to 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()); // finally add that dto to List dtos.add(weatherDto); } return dtos; ,您必须将List<WeatherDto>调整为extends StdDeserializer<WeatherDto>