代码之家  ›  专栏  ›  技术社区  ›  aurorashpo

难以理解如何将JSON映射/转换为Java对象

  •  0
  • aurorashpo  · 技术社区  · 3 年前

    你好:D我正在尝试从API(openweathermap.org)获取JSON字符串。我已经完成了API调用,我已经获取了该字符串,甚至使用gson库将其转换为“漂亮”的JSON格式,但我不明白如何将字符串中的值映射为单独的可访问值。

    我在Android Studio IDE中用Java编码:)

    原始JSON字符串的外观如下: {“coord”:{“lon”:50,“lat”:50},“list”:[{“main”:{《aqi》:1},“components”:{(co):267.03,“no”:0,“no2”:0.47,“o3”:76.53,“so2”:1.65,“pm2_5”:0.87,“pm10”:3.09,“nh3”:0.07},“dt”:1640437200}}

    我有一个名为airPollution的separate类,我将初始化这些值,例如 private String coord等,但我似乎无法理解JSON字符串的复杂性, coord是一个包含lon和lat键的列表吗?JSON的列表部分也是如此。

    这是当前的代码,不多:我已经注释掉了我试图摆弄的东西,如果有什么不清楚的地方,请告诉我。任何建议都很受欢迎,只是想把我的头绕过来:)我也使用了jsonviewer.stack.hu,这有点帮助,但我仍然不知道该如何构建列表。

     protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            String URL = "https://api.openweathermap.org/data/2.5/air_pollution?lat=50&lon=50&appid=0140f9110ece5d6477b5ac95aba2020d";
    
            //create a request queue
    
            RequestQueue requestQueue = Volley.newRequestQueue(this);
    
            // construct request
            //you can use json array or json object request or string request
    
            JsonObjectRequest objectRequest = new JsonObjectRequest(
                    Request.Method.GET,
                    URL,
                    null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            Log.e("Reponse", response.toString());
                            String json = response.toString();
                            JsonObject convertedObject = new Gson().fromJson(json, JsonObject.class);
                            Gson gson = new GsonBuilder().setPrettyPrinting().create(); // pretty print
                            String prettyJson = gson.toJson(json);
                            System.out.println(prettyJson);
    
                            //JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
                            //Assert.assertTrue(jsonObject.isJsonObject());
                            //Assert.assertTrue(convertedObject.isJsonObject());
                            
                   //Assert.assertTrue(convertedObject.get("coord").getAsString().equals("lon"));
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.e("Reponse", error.toString());
                        }
                    }
    
            );
            requestQueue.add(objectRequest);
    
    }
    

    空气污染等级(根本不是我应该做什么的一般概念?)

    public class airPollution {
    
    
        private String coord;
        private String lon;
        private String lat;
    
        public String getCoord() {
            return coord;
        }
    
        public void setCoord(String coord) {
            this.coord = coord;
        }
    
        public String getLon() {
            return lon;
        }
    
        public void setLon(String lon) {
            this.lon = lon;
        }
    
        public String getLat() {
            return lat;
        }
    
        public void setLat(String lat) {
            this.lat = lat;
        }
    }
    
    1 回复  |  直到 3 年前
        1
  •  0
  •   Martin Zeitler    3 年前

    你需要通过 class 这是意料之中的,否则它不会知道它是什么:

    AirPollution convertedObject = new Gson().fromJson(json, AirPollutionResponse.class);
    

    虽然 class AirPollution 可能需要也可能不需要进一步的代码注释。。。这取决于字段名是否与输入的JSON字段名匹配。在Android上,模型类通常会有很多注释,例如,当它们与Retrofit(内部使用GSON)和Room一起使用时。

    另请参阅GSON user guide .


    该模型类与输入的JSON至少不匹配。。。因为阅读是带着信封的。

    {
        "coord": {
            "lon": 50,
            "lat": 50
        },
        "list": [{
            "main":{
                "aqi": 1
            },
            "components":{
                "co": 267.03,
                "no": 0,
                "no2": 0.47,
                "o3": 76.53,
                "so2": 1.65,
                "pm2_5": 0.87,
                "pm10": 3.09,
                "nh3": 0.07
            },
            "dt": 1640437200
        }]
    }
    

    现在删除的答案并没有错,因为这需要5!!要映射的Java类。

    等级 AirPollution :

    import com.google.gson.annotations.SerializedName;
    
    public class AirPollution {
    
        @SerializedName("co")
        private Double carbonMonoxide = 0.0;
    
        @SerializedName("no")
        private Double nitricOxide = 0.0;
    
        @SerializedName("no2")
        private Double nitrogenDioxide = 0.0;
    
        @SerializedName("o3")
        private Double ozone = 0.0;
    
        @SerializedName("so2")
        private Double sulfurDioxide = 0.0;
    
        @SerializedName("pm2_5")
        private Double particulateMatterTwoFive = 0.0;
    
        @SerializedName("pm10")
        private Double particulateMatterTen = 0.0;
    
        @SerializedName("nh3")
        private Double ammonia = 0.0;
        ...
    }
    

    包裹着 class List (其实不是列表):

    public class List {
    
        @SerializedName("dt")
        private int timestamp = 0;    
    
        @SerializedName("components")
        private AirPollution reading = null;
        ...
    }
    

    包裹着 class AirPollutionResponse :

    public class AirPollutionResponse {
    
        @SerializedName("list")
        private List list = null;
        ...
    }
    

    更多字段 空气污染 (相似 dt , lat , lng )需要手动设置。
    尽管可以映射嵌套类,但类只能被一维映射。
    当嵌套变得过于极端时,仍然可以为嵌套值添加getter。