Как десериализовать вложенный объект JSON с тем же именем, что и мой класс Java - PullRequest
1 голос
/ 08 ноября 2019

Я пытаюсь сопоставить этот JSON

{
"coord": {
    "lon": 26.94,
    "lat": 43.27
},
"weather": [
    {
        "id": 802,
        "main": "Clouds",
        "description": "scattered clouds",
        "icon": "03d"
    }
],
"base": "model",
"main": {
    "temp": 19.3,
    "pressure": 1012,
    "humidity": 66,
    "temp_min": 19.3,
    "temp_max": 19.3,
    "sea_level": 1012,
    "grnd_level": 971
},
"wind": {
    "speed": 6.91,
    "deg": 182
},
"clouds": {
    "all": 38
},
"dt": 1573204594,
"sys": {
    "country": "BG",
    "sunrise": 1573188939,
    "sunset": 1573224978
},
"timezone": 7200,
"id": 727233,
"name": "Shumen",
"cod": 200
}

Моему собственному созданному объекту Java

    package com.kosev.willitrain.model;
    import com.fasterxml.jackson.annotation.JsonAlias;
    import com.fasterxml.jackson.annotation.JsonProperty;
    import java.util.Map;

    public class Weather {
        @JsonProperty("name")
        private String cityName;
        private String type; // for weather type eg: Cloudy, Sunny, Raining etc...
        private float temp;
        private float tempMin;
        private float tempMax;
        private float windSpeed;
        private String icon;
        private float lon;
        private float lat;

        public Weather(){}

        @JsonProperty("main")
        private void unpackMain(Map<String,String> main) {
            temp = Float.parseFloat(main.get("temp"));
            tempMin = Float.parseFloat(main.get("temp_min"));
            tempMax = Float.parseFloat(main.get("temp_max"));
        }

        @JsonProperty("coord")
        private void unpackCoord(Map<String,String> coord) {
            lon = Float.parseFloat(coord.get("lon"));
            lat = Float.parseFloat(coord.get("lat"));
        }

        @JsonProperty("weather")
        private void unpackWeather(Map<String,String> weather) {
            type = weather.get("main");
            icon = weather.get("icon");
        }
    }

Я получаю следующую ошибку:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Невозможно десериализовать экземпляр java.util.LinkedHashMap<java.lang.Object,java.lang.Object> из токена START_ARRAY в [Source: (PushbackInputStream);строка: 1, столбец: 46] (через цепочку ссылок: com.kosev.willitrain.model.Weather ["weather"])

Ответы [ 2 ]

1 голос
/ 08 ноября 2019
    package com.sample.demo;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class DemoApplicationTests {

    public static void main(String args[]) throws JsonParseException, JsonMappingException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        String response = "{\n" + "\"coord\": {\n" + "    \"lon\": 26.94,\n" + "    \"lat\": 43.27\n" + "},\n"
                + "\"weather\": [\n" + "    {\n" + "        \"id\": 802,\n" + "        \"main\": \"Clouds\",\n"
                + "        \"description\": \"scattered clouds\",\n" + "        \"icon\": \"03d\"\n" + "    }\n"
                + "],\n" + "\"base\": \"model\",\n" + "\"main\": {\n" + "    \"temp\": 19.3,\n"
                + "    \"pressure\": 1012,\n" + "    \"humidity\": 66,\n" + "    \"temp_min\": 19.3,\n"
                + "    \"temp_max\": 19.3,\n" + "    \"sea_level\": 1012,\n" + "    \"grnd_level\": 971\n" + "},\n"
                + "\"wind\": {\n" + "    \"speed\": 6.91,\n" + "    \"deg\": 182\n" + "},\n" + "\"clouds\": {\n"
                + "    \"all\": 38\n" + "},\n" + "\"dt\": 1573204594,\n" + "\"sys\": {\n" + "    \"country\": \"BG\",\n"
                + "    \"sunrise\": 1573188939,\n" + "    \"sunset\": 1573224978\n" + "},\n" + "\"timezone\": 7200,\n"
                + "\"id\": 727233,\n" + "\"name\": \"Shumen\",\n" + "\"cod\": 200\n" + "}";
        Weather weather = objectMapper.readValue(response, Weather.class);
    }
}

@JsonIgnoreProperties(ignoreUnknown = true)
class Weather {
    @JsonProperty("name")
    private String cityName;
    private String type; // for weather type eg: Cloudy, Sunny, Raining etc...
    private float temp;
    private float tempMin;
    private float tempMax;
    private float windSpeed;
    private String icon;
    private float lon;
    private float lat;

    @JsonIgnoreProperties("base")
    public Weather() {
    }

    @JsonProperty("main")
    private void unpackMain(Map<String, String> main) {
        temp = Float.parseFloat(main.get("temp"));
        tempMin = Float.parseFloat(main.get("temp_min"));
        tempMax = Float.parseFloat(main.get("temp_max"));
    }

    @JsonProperty("coord")
    private void unpackCoord(Map<String, String> coord) {
        lon = Float.parseFloat(coord.get("lon"));
        lat = Float.parseFloat(coord.get("lat"));
    }

    @JsonProperty("weather")
    private void unpackWeather(List<Map<String, String>> weather) {
        System.out.println(weather);
        type = weather.get(0).get("main"); // Taken first element , change as per your requirement
        icon = weather.get(0).get("icon");
    }
}

Погода должна быть списком карты, а не картой.

1 голос
/ 08 ноября 2019

Это ваша структура:

public class JsonClass {
    Coord coord;
    List<Weather> weather;
    String base;
    Main main;
    Wind wind;
    Clouds clouds;
    long dt;
    Sys sys;
    int timezone;
    int id;
    String name;
    int cod;

    private class Coord {
        private float lon;
        private float lat;
    }

    private class Weather {
        int id;
        String main;
        String description;
        String icon;
    }

    private class Main {
        float temp;
        int pressure;
        ...
    }

    private class Wind {
        float speed;
        int deg;
    }

    private class Clouds {
        int all;
    }

    private class Sys {
        String country;
        long sunrise;
        long sunset;
    }
  }

Чтобы прочитать его, просто позвоните readValue:

ObjectMapper MAPPER = new ObjectMapper();
JsonClass jsnClz = MAPPER .readValue(json, JsonClass.class);

Не забудьте добавить getter / setter или использовать lombokаннотаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...