Retrofit2 не может получить ежемесячные данные о валюте из API - PullRequest
0 голосов
/ 06 июня 2019

Я пытаюсь создать приложение, которое будет показывать пользователю указанные им месячные курсы валют.Сейчас, только для целей тестирования, я хотел бы получать месячные ставки в долларах США.Но я уже пытался сделать это несколькими способами, и каждый раз, когда мое приложение вылетает.Вот самая новая попытка.

Модифицированный вызов

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_currency_detailed);

    textView = (TextView) findViewById(R.id.error_test);

    String url = "https://api.exchangeratesapi.io/";
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    Api api = retrofit.create(Api.class);
    Call<testModel> modelCall = api.getMonthTest("2018-01-01", "2018-02-01", "USD");
    modelCall.enqueue(new Callback<testModel>() {
        @Override
        public void onResponse(Call<testModel> call, Response<testModel> response) {
            if (!response.isSuccessful()) {
                textView.setText(response.code());
            }

            List<testModel> models = Collections.singletonList(response.body());
            for (testModel model : models) {
                model.rates.put("2018-01-19",model.testRATES.getUsd());
                Iterator<Map.Entry<String, Double>> iterator = model.getRates().entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry entry = (Map.Entry) iterator.next();

                    key = (String) entry.getKey();
                    value = (Double) entry.getValue();

                    textView.append(key+"    "+value+"\n");
                }
            }
        }
        @Override
        public void onFailure(Call<testModel> call, Throwable t) {
            textView.setText(t.getMessage());
            System.out.println(t.getMessage());
        }
    });
 }
}

Метод интерфейса

@GET("history")
Call<testModel> getMonthTest(
        @Query("start_at") String startAt,
        @Query("end_at") String endAt,
        @Query("symbols") String symbol);

Класс POJO

@SerializedName("end_at")
String endAt;
@SerializedName("start_at")
String startAt;
@SerializedName("rates")
Map<String, Double> rates;

Rates testRATES;


public String getEndAt() {
    return endAt;
}

public String getStartAt() {
    return startAt;
}

public Map<String, Double> getRates() {
    return rates;
}

public class Rates{
    @SerializedName("USD")
    Double usd;

    public Double getUsd() {
        return usd;
    }
}

JSON-ответ

  {
  "base": "EUR",
  "rates": {
    "2018-01-30": {
      "USD": 1.2421
    },
    "2018-01-15": {
      "USD": 1.2277
    },
    "2018-01-03": {
      "USD": 1.2023
    },
    "2018-02-01": {
      "USD": 1.2459
    },
    "2018-01-26": {
      "USD": 1.2436
    },
    "2018-01-12": {
      "USD": 1.2137
    },
    "2018-01-19": {
      "USD": 1.2255
    },
    "2018-01-16": {
      "USD": 1.223
    },
    "2018-01-22": {
      "USD": 1.2239
    },
    "2018-01-10": {
      "USD": 1.1992
    },
    "2018-01-08": {
      "USD": 1.1973
    },
    "2018-01-25": {
      "USD": 1.2407
    },
    "2018-01-29": {
      "USD": 1.2379
    },
    "2018-01-24": {
      "USD": 1.2352
    },
    "2018-01-11": {
      "USD": 1.2017
    },
    "2018-01-02": {
      "USD": 1.2065
    },
    "2018-01-31": {
      "USD": 1.2457
    },
    "2018-01-05": {
      "USD": 1.2045
    },
    "2018-01-18": {
      "USD": 1.2235
    },
    "2018-01-23": {
      "USD": 1.2249
    },
    "2018-01-04": {
      "USD": 1.2065
    },
    "2018-01-17": {
      "USD": 1.2203
    },
    "2018-01-09": {
      "USD": 1.1932
    }
  },
  "end_at": "2018-02-01",
  "start_at": "2018-01-01"
}

Ошибка

java.lang.IllegalStateException: Expected a double but was BEGIN_OBJECT at line 1 column 38 path $.rates.

Где может быть проблема?

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

Проблема в @SerializedName("rates") Map<String, Double> rates;.

У вас есть:

 "rates": {
    "2018-01-30": {
      "USD": 1.2421
    }
 }

Итак, у вас есть Map<String, Double>, где вы, вероятно, должны иметь Map<String, Rate>, как в:

public class Rate {
    @SerializedName("USD")
    Double usd;

    public Double getUsd() {
        return usd;
    }
}

Не уверен, что Map<String, Rate> будет работать, так как строка не является ключевой и довольно динамичной, поэтому вам, вероятно, придется выполнить некоторую пользовательскую десериализацию.

Refs:

0 голосов
/ 06 июня 2019

Ваша модель неверна. rates является Map<String, Map<String, Double>>.

...