【问题标题】:Retrofit: Parse nested JSON elements to a list改造:将嵌套的 JSON 元素解析为列表
【发布时间】:2019-05-08 23:18:50
【问题描述】:

我在尝试将此 JSON 响应解析为 "properties" 元素列表时遇到了困难。我的 JSON 如下所示:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "mag": 6.6,
                "place": "192km ESE of Tadine, New Caledonia"
            }
        },
        {
            "type": "Feature",
            "properties": {
                "mag": 7.5,
                "place": "168km ESE of Tadine, New Caledonia"
            }
        },
        {
            "type": "Feature",
            "properties": {
                "mag": 6,
                "place": "155km ESE of Tadine, New Caledonia"
            }
        }
    ]
}

这是包含地震详细信息的响应,所以基本上"features" 中的每个"properties" 都是我想要的 POJO,但它们都只是在一个列表中。这是我的Earthquake 课程:

public class Earthquake {
    @SerializedName("mag")
    private double magnitude;
    @SerializedName("place")
    private String location;

    public   Earthquake(double magnitude, String location) {
        this.magnitude = magnitude;
        this.location = location;
    }
    // getters
}

我尝试过建议here 进行自定义反序列化。它给了我错误

预期为 BEGIN_ARRAY,但在第 1 行第 2 列路径 $ 处为 BEGIN_OBJECT

建议我尝试解析 JsonObject 而不是 JsonArray。这是我使用的反序列化器。

public class EarthquakeDeserializer implements JsonDeserializer<ArrayList<Earthquake>> {

    @Override
    public ArrayList<Earthquake> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        // get list of "features"
        JsonElement features = json.getAsJsonObject().get("features");

        JsonArray earthquakeElements = new JsonArray();
        for (JsonElement feature : features.getAsJsonArray()){
            JsonElement properties = feature.getAsJsonObject().get("properties");
            earthquakeElements.add(properties);
        }

        Type listType = new TypeToken<ArrayList<Earthquake>>(){}.getType();

        return new Gson().fromJson(earthquakeElements, listType);
    }
}

关于这里发生了什么的任何想法?

【问题讨论】:

  • 您可以通过 Gson 库轻松反序列化这些东西。你能用吗?
  • @JayDangar 我只是遵循改造方式。对Gson还不是很熟悉。主要是我只是想通过反序列化来避免创建太多的类。

标签: java android json api retrofit


【解决方案1】:

您可以为您的 Json 创建这种 POJO 类,无论您是否只想要响应主体的单个部分,您都需要为整个响应创建 POJO,并且您需要从该 POJO 中获取适当的属性。 ->

这是你的主要 json 对象 ->

public class Example {

    @SerializedName("type")
    @Expose
    private String type;
    @SerializedName("features")
    @Expose
    private List<Feature> features = null;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public List<Feature> getFeatures() {
        return features;
    }

    public void setFeatures(List<Feature> features) {
        this.features = features;
    }

}

这是你的要素类 ->

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Feature {

    @SerializedName("type")
    @Expose
    private String type;
    @SerializedName("properties")
    @Expose
    private Properties properties;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

}

这是你的属性类 ->

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Properties {

    @SerializedName("mag")
    @Expose
    private Integer mag;
    @SerializedName("place")
    @Expose
    private String place;

    public Integer getMag() {
        return mag;
    }

    public void setMag(Integer mag) {
        this.mag = mag;
    }

    public String getPlace() {
        return place;
    }

    public void setPlace(String place) {
        this.place = place;
    }

}

创建此类后,您可以通过 GSON 库将 JSON 序列化为 POJO,具体操作方法可以参考 HussainAbbas 的回答。

现在您可以通过创建响应类的对象来获得任何东西,并且通过该对象您可以访问您想要的任何属性。谢谢。

【讨论】:

  • 我可能想知道是否可以避免创建太多类。深度嵌套的 JSON 使用 Retrofit 一定很乏味。
  • 你可以从根对象到你喜欢的对象。
  • 此外,您可以通过jsonschema2pojo.org 这个网站自动执行从 Json 创建 POJO 类的任务,如果您使用的是 android studio、eclipse、Intellij Ide,那么还有插件。可以从 JSON 为您生成 POJO 类。所以你也不需要创建 POJO 类。您正在查看的我生成的类仅来自 jsonschema2pojo 网站。所以它并不像你想象的那么乏味。 :)
  • 哇。不知道他们的存在!非常感谢!
  • 创建一个名为 POJO 的包,并在其中创建不同的 java POJO 类。
【解决方案2】:

看看这个

package com.example;

import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Example {

@SerializedName("type")
@Expose
private String type;
@SerializedName("features")
@Expose
private List<Feature> features = null;

  public String getType() {
    return type;
  }

  public void setType(String type) { 
    this.type = type;
  }

  public List<Feature> getFeatures() {
    return features;
  }

  public void setFeatures(List<Feature> features) {
   this.features = features;
  }

}

------------------------com.example.Feature.java----- ------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Feature {

 @SerializedName("type")
 @Expose
 private String type;
 @SerializedName("properties")
 @Expose
 private Properties properties;

 public String getType() { 
   return type;
 }

 public void setType(String type) {
   this.type = type;
 }

 public Properties getProperties() {
   return properties;
 }

 public void setProperties(Properties properties) {
   this.properties = properties; 
 }

} ------------------------------------com.example.Properties.java-------- --------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Properties {

   @SerializedName("mag")
   @Expose
   private Integer mag;
   @SerializedName("place")
   @Expose
   private String place;

   public Integer getMag() {
       return mag;
   }

   public void setMag(Integer mag) {
      this.mag = mag;
   } 

   public String getPlace() {
     return place;
   }

   public void setPlace(String place) {
     this.place = place;
   }

 }

在此之后添加这个...在您的改造响应中

Gson gson = new Gson()
String data = gson.toJson(response.body());
LoginResponse loginResponse = gson.fromJson(dataString,LoginResponse.class);
Example example = gson.fromJson(dataString,Example.class);
String feature_proprerties_mag = example.getFeatures().getProperties().getMag

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2020-05-21
    • 1970-01-01
    • 2018-09-23
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多