【问题标题】:Retrofit: Json with 2 dynamic fields(one field in the other) into Gson改造:将带有 2 个动态字段(另一个字段)的 Json 转换为 Gson
【发布时间】:2019-07-15 19:30:03
【问题描述】:

使用改造我需要调用一个 Api,它给了我一个带有动态字段的 json,这些字段根据我提供的参数而变化。例如,对于“符号”参数“ETH”、“XRP”和“转换”参数“ USD”,响应将是以下 Json:

{
   "data":{
      "ETH":{
         "id":1027,
         "name":"Ethereum",
         "symbol":"ETH",
         "quote":{
            "USD":{
               "price":225.911630584,
               "volume_24h":9744372948.14671,
               "percent_change_1h":-2.87302,
               "percent_change_24h":-4.94698,
               "percent_change_7d":-26.9517,
               "market_cap":24152563209.793915
            }
         }
      },
      "XRP":{
         "id":52,
         "name":"XRP",
         "symbol":"XRP",
         "quote":{
            "USD":{
               "price":0.31390356279,
               "volume_24h":1610830847.99846,
               "percent_change_1h":-1.37633,
               "percent_change_24h":-0.0736244,
               "percent_change_7d":-21.4656,
               "market_cap":13361806194.547878
            }
         }
      }
   }
}

我创建的 ApiClass 如下:

public class ApiConstants {
    public static String APP_KEY="xxxx-xxxx-xxxx-xxxx";
    public static String BASE_URL = "https://pro-api.coinmarketcap.com/";
    public static final String CRYPTOCURRENCYQUOTES="v1/cryptocurrency/quotes/latest";

我有这个界面:

public interface CoinToCoin {
    @GET(ApiConstants.CRYPTOCURRENCYINFO)
    Call<MainClass...base class that must be created> convertCoinToCoin(@Header("X-CMC_PRO_API_KEY") String appkey,                                                
               @Query("symbol") String 
coinToCoinConvertedCoinSymbol, @Query("convert") String 
coinToCoinSymbol);
}

我的改造:

    public class RetrofitClient {
        private static RetrofitClient instance = null;
        private Retrofit retrofit;
        private OkHttpClient client;
        private CoinToCoin coinToCoin;

    private RetrofitClient() {

        OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
        client = okHttpBuilder.build();
        retrofit = new Retrofit.Builder().baseUrl(ApiConstants.BASE_URL).addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        coinToCoin= retrofit.create(CoinToCoin.class);
    }

    public static RetrofitClient getInstance() {
        if (instance == null) {
            instance = new RetrofitClient();
        }
        return instance;
    }

    public CoinToCoin getCoinToCoin() { return coinToCoin; 
}

}

在我的主要活动中,我必须实例化我的 RetrofitClient

private RetrofitClient retrofit;
retrofit = RetrofitClient.getInstance();

然后拨打电话检索我需要的数据:

    Call<MainClass...this must be created> call =retrofit.getCoinToCoin().convertCoinToCoin(ApiConstants.CRYPTOCURRENCYINFO,"ETH,XRP","USD");
        call.enqueue(new Callback<MainClass...this must be created>() {
            @Override
            public void onResponse(Call<MainClass...this must be created> 
call, Response<MainClass...this must be created> response) {

           }

            @Override
            public void onFailure(Call<MainClass...this must be created> 
call, Throwable t) {

            }
        });

据我所知,最好的方法是使用 HashMaps 和反序列化,但我不知道怎么做。 另外我真的不知道我需要创建的类应该是什么样子。

请明确并告诉我如何一步一步地做。我是新手。

【问题讨论】:

    标签: android json gson retrofit2


    【解决方案1】:

    就我个人而言,我会像你说的那样去买一张地图。根据您的 json,您可以为每个硬币定义一个对象:

    public class Quote {      
      @SerializedName("price")
      private double price;
      @SerializedName("volume_24h")
      private double volume24h;
      @SerializedName("percent_change_1h")
      private double percentChange1h;
      @SerializedName("percent_change_24h")
      private double percentChange24h;
      @SerializedName("percent_change_7d")
      private double percentChange7d;
      @SerializedName("market_cap")
      private double marketCap;
      // getters and setters
    }
    
    public class Coin {
      @SerializedName("id")
      private int id;
      @SerializedName("name")
      private String name;
      @SerializedName("symbol")
      private String symbol;
      @SerializedName("quote")
      private Map<String, Quote> quote;
      // getters and setters
    }
    

    我不确定数据是否始终相同,但如果不是,您可以采用类似的方法:

    public class CoinResponse {
      @SerializedName("data")
      private Map<String, Coin> data;
      // getters and setters
    }
    

    现在您可以使用CoinResponse 作为改造界面的响应。

    【讨论】:

    • “数据”字段始终相同。唯一变化的字段是我给出的示例中的“ETH”、“XRP”、“USD”。
    • 好的,那么我的解决方案应该成立
    猜你喜欢
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 2017-03-31
    • 1970-01-01
    • 2021-12-10
    • 2011-11-30
    相关资源
    最近更新 更多