【问题标题】:JSON with Dynamic Keys while using Retrofit in Android在 Android 中使用 Retrofit 时带有动态键的 JSON
【发布时间】:2017-12-04 05:11:10
【问题描述】:

我是在 Android 上使用 Retrofit 的新手。我被困在向REST Api 发出请求并且响应具有动态键的地步。谁能告诉我解析 JSON 这样的最佳方法是什么。

{
  "Meta Data": {
    "1. Information": "Intraday (1min) prices and volumes",
    "2. Symbol": "MSFT",
    "3. Last Refreshed": "2017-12-01 16:00:00",
    "4. Interval": "1min",
    "5. Output Size": "Compact",
    "6. Time Zone": "US/Eastern"
  },
  "Time Series (1min)": {
    "2017-12-01 16:00:00": {
      "1. open": "84.2000",
      "2. high": "84.2600",
      "3. low": "84.1800",
      "4. close": "84.2000",
      "5. volume": "3311341"
    },
    "2017-12-01 15:59:00": {
      "1. open": "84.2500",
      "2. high": "84.2600",
      "3. low": "84.2000",
      "4. close": "84.2000",
      "5. volume": "175169"
    },
    "2017-12-01 15:58:00": {
      "1. open": "84.2800",
      "2. high": "84.3000",
      "3. low": "84.2400",
      "4. close": "84.2550",
      "5. volume": "139520"
    }

  }
}

【问题讨论】:

  • TreeMap<String, Object> 用于所有动态键控对象
  • 你最好手动解析它
  • 检查this

标签: java android json retrofit2


【解决方案1】:

如果您使用的是 Retrofit,那么您可以直接将其解析为某个模型,例如 TestModel 根据您的要求调用这样的东西。

@GET("your endpoint")
Call<TestModel> getTestData();

在这里你会得到数据

public void getTestData(){
    mApiServiceNetwork.getNetworkService(null,WebConstants.API_ENDPOINT)
            .getTestData()
            .enqueue(new Callback<TestModel>() {
                @Override
                public void onResponse(final Call<TestModel> call, final Response<TestModel> response) {
                    if (response.code()==200){
                        //handle the response
                        TestModel testModel = response.body();
                    }else{
                        //handle the error
                    }
                }

                @Override
                public void onFailure(final Call<TestModel> call, final Throwable t) {

                }
            });
}

如果您在 JSON 对象中获取数据,请这样做。

 private TestModel getTestModel(JsonObject jsonObject){
        Gson gson = new Gson();
        TestModel  testModel = gson.fromJson(jsonObject,TestModel.class);
        return testModel;
    }

如果你在 String 中获取数据然后解析成 Json 对象然后调用上面的方法是如何将字符串转换为 json 对象。

JsonObject jsonParser = new JsonParser().parse(json).getAsJsonObject();

最重要的是,对于这两种情况,您的 TestModel 应该如下所示。

public class TestModel {
@SerializedName("Meta Data")
@Expose
private MetaModel mMetaModel;

public MetaModel getMetaModel() {
    return mMetaModel;
}

public void setMetaModel(final MetaModel metaModel) {
    mMetaModel = metaModel;
}

public Map<String, TimeModel> getTimeModel() {
    return mTimeModel;
}

public void setTimeModel(final Map<String, TimeModel> timeModel) {
    mTimeModel = timeModel;
}

@SerializedName("Time Series (1min)")

@Expose
private Map<String,TimeModel> mTimeModel;

public static class MetaModel{

    @SerializedName("1. Information")
    @Expose
    private String _1Information;
    @SerializedName("2. Symbol")
    @Expose
    private String _2Symbol;
    @SerializedName("3. Last Refreshed")
    @Expose
    private String _3LastRefreshed;
    @SerializedName("4. Interval")
    @Expose
    private String _4Interval;
    @SerializedName("5. Output Size")
    @Expose
    private String _5OutputSize;
    @SerializedName("6. Time Zone")
    @Expose
    private String _6TimeZone;

    public String get_1Information() {
        return _1Information;
    }

    public void set_1Information(final String _1Information) {
        this._1Information = _1Information;
    }

    public String get_2Symbol() {
        return _2Symbol;
    }

    public void set_2Symbol(final String _2Symbol) {
        this._2Symbol = _2Symbol;
    }

    public String get_3LastRefreshed() {
        return _3LastRefreshed;
    }

    public void set_3LastRefreshed(final String _3LastRefreshed) {
        this._3LastRefreshed = _3LastRefreshed;
    }

    public String get_4Interval() {
        return _4Interval;
    }

    public void set_4Interval(final String _4Interval) {
        this._4Interval = _4Interval;
    }

    public String get_5OutputSize() {
        return _5OutputSize;
    }

    public void set_5OutputSize(final String _5OutputSize) {
        this._5OutputSize = _5OutputSize;
    }

    public String get_6TimeZone() {
        return _6TimeZone;
    }

    public void set_6TimeZone(final String _6TimeZone) {
        this._6TimeZone = _6TimeZone;
    }
}
public static class TimeModel{
    @SerializedName("1. open")
    @Expose
    private String _1Open;
    @SerializedName("2. high")
    @Expose
    private String _2High;
    @SerializedName("3. low")
    @Expose
    private String _3Low;
    @SerializedName("4. close")
    @Expose
    private String _4Close;
    @SerializedName("5. volume")
    @Expose
    private String _5Volume;

    public String get_1Open() {
        return _1Open;
    }

    public void set_1Open(final String _1Open) {
        this._1Open = _1Open;
    }

    public String get_2High() {
        return _2High;
    }

    public void set_2High(final String _2High) {
        this._2High = _2High;
    }

    public String get_3Low() {
        return _3Low;
    }

    public void set_3Low(final String _3Low) {
        this._3Low = _3Low;
    }

    public String get_4Close() {
        return _4Close;
    }

    public void set_4Close(final String _4Close) {
        this._4Close = _4Close;
    }

    public String get_5Volume() {
        return _5Volume;
    }

    public void set_5Volume(final String _5Volume) {
        this._5Volume = _5Volume;
    }
}

}

关键是如果我们使用 Map&lt;K,V&gt; 进行改造,如果模型就像 JSON 中的一样,它会自动将其解析为模型。

【讨论】:

  • 这就是我要找的。我想使用 Retrofit 并希望避免任何自定义 JSON 解析。谢谢
【解决方案2】:

如果要手动解析 JsonString,请按照以下代码:

        JSONObject object = new JSONObject(jsonString);
        Map<String, Object> metaDataMap = toMap(object.getJSONObject("Meta Data"));
        displayMap(metaDataMap);

        Map<String, Object> timeSeriesMap = toMap(object.getJSONObject("Time Series (1min)"));
        displayMap(timeSeriesMap);

toMap方法:

public Map<String, Object> toMap(JSONObject object) throws JSONException {
        Map<String, Object> map = new TreeMap<String, Object>();  // TreeMap(for getting data in sorted order[Ascending])

        Iterator<String> keysItr = object.keys();
        while(keysItr.hasNext()) {
            String key = keysItr.next();
            Object value = object.get(key);

            if(value instanceof JSONObject) {
                value = toMap((JSONObject) value);
            }
            map.put(key, value);
        }
        return map;
    }

displayMap方法:

public void displayMap(Map<String, Object> myMap) {
        Iterator iterator = myMap.entrySet().iterator();
        while(iterator.hasNext()) {
            Map.Entry mentry = (Map.Entry)iterator.next();
             System.out.println("key is: "+ mentry.getKey() + " & Value is: " + mentry.getValue());
        }
    }

输出:

key is: 1. Information & Value is: Intraday (1min) prices and volumes
key is: 2. Symbol & Value is: MSFT
key is: 3. Last Refreshed & Value is: 2017-12-01 16:00:00
key is: 4. Interval & Value is: 1min
key is: 5. Output Size & Value is: Compact
key is: 6. Time Zone & Value is: US/Eastern

key is: 2017-12-01 15:58:00 & Value is: {1. open=84.2800, 2. high=84.3000, 3. low=84.2400, 4. close=84.2550, 5. volume=139520}
key is: 2017-12-01 15:59:00 & Value is: {1. open=84.2500, 2. high=84.2600, 3. low=84.2000, 4. close=84.2000, 5. volume=175169}
key is: 2017-12-01 16:00:00 & Value is: {1. open=84.2000, 2. high=84.2600, 3. low=84.1800, 4. close=84.2000, 5. volume=3311341}

【讨论】:

    【解决方案3】:

    我认为这可能会对您有所帮助:

      JSONObject timeJsonObject = mainObject.getJSONObject("Time Series (1min)");
    
    
    
        Iterator<String> keysItr = timeJsonObject.keys();
        while (keysItr.hasNext()) {
            String key = keysItr.next();
    
            //now here you get key as : 2017-12-01 16:00:00
    
            //do here code as:
    
            JSONObject individualObject = timeJsonObject.getJSONObject(key);
    
            String openTime = individualObject.getString("1. open");
            String highTime = individualObject.getString("1. high");
            String lowTime = individualObject.getString("1. low");
            String closeTime = individualObject.getString("1. close");
            String volumeTime = individualObject.getString("1. volumne");
    
    
        }
    

    这里“while-loop”迭代“2017-12-01 16:00:00,2017-12-01 15:59:00,2017-12-01 15:58:00”等所有键在。它将迭代此部分中将添加多少键。

    【讨论】:

      猜你喜欢
      • 2018-05-24
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 1970-01-01
      相关资源
      最近更新 更多