如何处理API JSON响应,它在JSON名称字段中具有值

时间:2017-10-25 18:08:20

标签: java android json retrofit

我一直在使用 retrofit JSON 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
            }
    }
}
公司股票代码是

APPL GOOGL 。我将它们视为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;
    }

}

因此,如果我有特斯拉,Facebook,...股票,我必须为每只股票创建新的类。

我想知道,我想如何使用改装处理上述响应?我可以对上述API响应做任何解决方法,以便我可以使用改造来优雅地处理它们吗?

如果我可以向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;
    }

}

3 个答案:

答案 0 :(得分:0)

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

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

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

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

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

答案 1 :(得分:0)

这不仅仅是一个答案,也可能是一个建议。

开发人员必须有一些理由支持开发代码以创建JSON响应的方式。您可能会问的问题是,其他一些应用程序是否也以这种格式锁定响应,或者是否有正在开发的应用程序需要这种格式的数据等。如果有其他应用程序使用这些数据,则答案为@ Harminder Singh似乎是正确的方式。如果只是由您开发的应用程序消耗此响应,我认为没有任何理由按照您的方式使用它,您可以要求开发人员将其更改为您的规范。

答案 2 :(得分:0)

我找到了解决方法。

正在使用字符串映射到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;
    }

}