【问题标题】:How to deal with API JSON response, which is having value in JSON name field如何处理在 JSON 名称字段中具有值的 API JSON 响应
【发布时间】:2018-04-06 22:47:28
【问题描述】:

一直以来,我都在使用 retrofitJSON to POJO tool,以便让 Android 应用程序与 API 服务器通信。

API 服务器使用 JSON 作为响应。

最近遇到股票相关的回复,是这样的

{
    "APPL": {
            "quote": {
                "symbol": "AAPL",
                "lastPrice": 1.23
            },
            "stats": {
                "dividendRate":2.52
            }
    },

    "GOOGL": {
            "quote": {
                "symbol": "GOOGL",
                "lastPrice": 4.56
            },
            "stats": {
                "dividendRate":7.89
            }
    }
}

APPLGOOGL 是公司股票代码。我将它们视为value。因此,我不希望它们被放置在 JSON 的名称字段(左侧)

我几乎无法为上述响应生成一组合适的类。

如果我将 JSON 输出直接插入 http://www.jsonschema2pojo.org/ ,我得到的结果是

public class BatchResponse {

    @SerializedName("APPL")
    @Expose
    private APPL aPPL;
    @SerializedName("GOOGL")
    @Expose
    private GOOGL gOOGL;

    public APPL getAPPL() {
        return aPPL;
    }

    public void setAPPL(APPL aPPL) {
        this.aPPL = aPPL;
    }

    public GOOGL getGOOGL() {
        return gOOGL;
    }

    public void setGOOGL(GOOGL gOOGL) {
        this.gOOGL = gOOGL;
    }

}

public class APPL {

    @SerializedName("quote")
    @Expose
    private Quote quote;
    @SerializedName("stats")
    @Expose
    private Stats stats;

    public Quote getQuote() {
        return quote;
    }

    public void setQuote(Quote quote) {
        this.quote = quote;
    }

    public Stats getStats() {
        return stats;
    }

    public void setStats(Stats stats) {
        this.stats = stats;
    }

}

public class GOOGL {

    @SerializedName("quote")
    @Expose
    private Quote quote;
    @SerializedName("stats")
    @Expose
    private Stats stats;

    public Quote getQuote() {
        return quote;
    }

    public void setQuote(Quote_ quote) {
        this.quote = quote;
    }

    public Stats getStats() {
        return stats;
    }

    public void setStats(Stats stats) {
        this.stats = stats;
    }

}

public class Quote {

    @SerializedName("symbol")
    @Expose
    private String symbol;
    @SerializedName("lastPrice")
    @Expose
    private double lastPrice;

    public String getSymbol() {
        return symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public double getLastPrice() {
        return lastPrice;
    }

    public void setLastPrice(double lastPrice) {
        this.lastPrice = lastPrice;
    }

}

public class Stats {

    @SerializedName("dividendRate")
    @Expose
    private double dividendRate;

    public double getDividendRate() {
        return dividendRate;
    }

    public void setDividendRate(double dividendRate) {
        this.dividendRate = dividendRate;
    }

}

因此,如果我有 Tesla、Facebook 等股票,我必须为每只股票创建新类。

我想知道,我想如何使用 retrofit 来处理上述响应?我可以对上述 API 响应采取什么解决方法,以便我可以使用 retrofit 优雅地处理它们?

如果我可以向API设计者提出以下响应格式,是否有意义,以便应用程序开发人员可以更轻松地处理此类响应?

{
    "batch" : [
        {
            "quote" : {
                "symbol": "AAPL",
                "lastPrice": 1.23
            },
            "stats" : {
                "dividendRate":2.52
            }
        },
        {
            "quote" : {
                "symbol": "GOOGL",
                "lastPrice": 4.56
            },
            "stats" : {
                "dividendRate":7.89
            }
        }
    ]
}

如果使用上面提出的 API 响应,我可以生成更好的 POJO 类。

public class BatchResponse {

    @SerializedName("batch")
    @Expose
    private List<Batch> batch = null;

    public List<Batch> getBatch() {
        return batch;
    }

    public void setBatch(List<Batch> batch) {
        this.batch = batch;
    }

}

public class Quote {

    @SerializedName("symbol")
    @Expose
    private String symbol;
    @SerializedName("lastPrice")
    @Expose
    private double lastPrice;

    public String getSymbol() {
        return symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public double getLastPrice() {
        return lastPrice;
    }

    public void setLastPrice(double lastPrice) {
        this.lastPrice = lastPrice;
    }

}

public class Stats {

    @SerializedName("dividendRate")
    @Expose
    private double dividendRate;

    public double getDividendRate() {
        return dividendRate;
    }

    public void setDividendRate(double dividendRate) {
        this.dividendRate = dividendRate;
    }

}

【问题讨论】:

    标签: java android json retrofit


    【解决方案1】:

    我想如何使用改造来处理上述响应?

    - 你只需要使用同一个类。只需将 SerializedName("APPL") 更改为 Tesla SerializedName("TESLA"),因为我们在内部得到相同的响应。所以我们不需要一次又一次地创建整个类。

    @SerializedName("APPL")
    @Expose
    private APPL aPPL;
    @SerializedName("GOOGL")
    @Expose
    private APPL aPPL;
    

    如果我可以向 API 设计者提出以下响应格式,让应用程序开发者可以更轻松地处理此类响应,是否有意义?

    • 是的,您可以使用这种格式。这是使 json 动态化的完美解决方案。

    【讨论】:

    • 但是,如何在运行时更改@SerializedName("GOOGL")?我们不知道即将到来的股票是什么,有多少。
    • 如果您不知道密钥,请选择第二种解决方案,让您的 json 像上面提到的那样动态化。
    【解决方案2】:

    这可能不仅仅是一个建议。

    开发人员必须有某种原因来开发用于创建 JSON 响应的代码的方式。您可能会问的问题是,是否有其他应用程序也在锁定这种格式的响应,或者是否有正在开发的应用程序需要这种格式的数据等。如果有其他应用程序使用数据,那么@的答案Harminder Singh 似乎是正确的方法。如果此响应仅由您正在开发的应用程序使用,我认为没有任何理由以您想要的方式使用它,您可以要求开发人员将其更改为您的规范。

    【讨论】:

      【解决方案3】:

      我设法找到了解决方法。

      它正在使用 String 到 BatchResponse 的映射

      看起来像

      Call<Map<String, BatchResponse>> batchMultipleQuoteStats(@Query("symbols") String symbols);
      

      BatchResponse 类是

      public class BatchResponse {
      
          @SerializedName("quote")
          @Expose
          private Quote quote;
          @SerializedName("stats")
          @Expose
          private Stats stats;
      
          public Quote getQuote() {
              return quote;
          }
      
          public void setQuote(Quote_ quote) {
              this.quote = quote;
          }
      
          public Stats getStats() {
              return stats;
          }
      
          public void setStats(Stats stats) {
              this.stats = stats;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-10
        • 2016-08-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多