当前位置: 首页 > 知识库问答 >
问题:

如何反序列化与Java类同名的嵌套JSON对象

华星文
2023-03-14

我正在尝试映射这个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");
        }
    }

我得到的错误是:

通用域名格式。fasterxml。杰克逊。数据绑定。exc.MismatchedInputException:无法反序列化java的实例。util。LinkedHashMap


共有2个答案

丌官晔
2023-03-14

这是你的结构:

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;
    }
  }

要读他的json,只需调用readValue

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

不要忘记添加getter/setter或使用lombok注释。

朱慈
2023-03-14
    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");
    }
}

天气应该是地图的列表,而不是地图。

 类似资料:
  • 我知道我可以创建一个单独的Report类,然后使用@JSONProperty将其嵌入到ReportResponse中。有没有一种方法可以避免这种情况,并用一个注释标记ReportResponse类,将它映射到JSON中的“Report”元素?

  • 问题内容: 我从看起来像这样的API获取JSON: 我尝试了几种方法来在c#对象中表示此JSON(太多内容无法在此处列出)。我已经尝试过使用列表和字典,这是我尝试表示它的最新示例: 这是我用来反序列化JSON的方法: 包含和。并且包含,但是是。因此,除了反序列化之外,什么都没有。 它应该很简单,但是由于某种原因我无法弄清楚正确的对象表示形式 问题答案: 要使用,即: 假设项目名称和随响应而变化,并

  • 问题内容: 我有一个Vendor对象,可以从一个单独的“ vendor” json序列中反序列化,但是我想将此序列反序列化为一个,我只是想不出如何让Jackson合作。有小费吗? 问题答案: 您的数据存在问题,因为您的数组中有内部 包装 对象。想必你的对象被设计成手柄,,,但每次的多个对象也都包裹在一个对象与单一属性。 我假设您正在使用Jackson 数据绑定 模型。 如果是这样,那么有两件事要考

  • 我之前的问题没有得到任何结果,可能是我问得不对,或者太详细了。 现在我的基本问题是,如何将一个具有一个类名的JSON对象反序列化为一个具有不同类名的Java对象? 例如,服务器发送/期望的JSON类是“18”(我对此控制为零)。我的Java班不可能是“18”,所以是“_18”。 简单地执行new Gson().fromjson()没有任何帮助,即使使用了不同的命名策略;_18对象始终为NULL。从

  • 我想实现一个功能,其中请求映射到正确的对象。是否有一种方法(除了自定义反序列化器)可以将请求按类型/基数映射到适当的对象?任何见解都将不胜感激!

  • 但它返回一个id为空且产品为空的对象。当然,我不需要为这个简单的操作编写自定义的吗?