Android Studio java.lang.IllegalStateException:预期 BEGIN_ARRAY 但 BEGIN_OBJECT 在第 1 行第 2 列路径 $

Andorid Studio java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

我知道这不是关于此错误的第一个问题。我到处都在寻找答案,但我找不到解决办法。当我 运行 我得到这个异常的代码;

java.lang.IllegalStateException:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 BEGIN_OBJECT $

主要Activity

public class MainActivity extends AppCompatActivity {
    ArrayList<Doviz> dovizs;

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

        Retrofit retrofit= new Retrofit.Builder()
                .baseUrl("https://finans.truncgil.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        DovizApi dovizApi = retrofit.create(DovizApi.class);

        Call<List<Doviz>> call = dovizApi.getDoviz();

      

        call.enqueue(new Callback<List<Doviz>>() {

            @Override
            public void onResponse(Call<List<Doviz>> call, Response<List<Doviz>> response) {
                System.out.println("deneme");
                List<Doviz> responseList= response.body();
                dovizs = new ArrayList<>(responseList);
                System.out.println(dovizs.get(0).USD);

            }

            @Override
            public void onFailure(Call<List<Doviz>> call, Throwable t) {
                System.out.println(t.fillInStackTrace());
            }
        });
    }
}

Java Class

public class Doviz {

    @SerializedName("Buying")
    public String USD;

}

界面

public interface DovizApi {
    @GET("today.json")
    Call<List<Doviz>> getDoviz();
}

我使用的列表 https://finans.truncgil.com/v3/today.json

几天来我一直在处理这个问题。希望能解决

检查点

  1. 类型

Json 如下所示

{
   "Update_Date":"2021-05-12 16:00:01",
   "USD":{
      "Buying":"8,3681",
      "Type":"Currency",
      "Selling":"8,3735",
      "Change":"%1,13"
   },
   ...
}

它不是 <List>USD 是 json

中的关键之一

所以 Call<List<Doviz>> 应该更改为 Call<Doviz>

  1. DTO(多维兹)

您可能需要 Buying USD 的值。 你是 DTO(Doviz) 应该有 属性 作为另一个像这样的 DTO

  class Doviz {
        @SerializedName("USD")
        CurrencyInfo usd;
       
        // else like this
        @SerializedName("EUR")
        CurrencyInfo eur;

        //...
  }

  class CurrencyInfo {
        //if Path(/v3) included
        @SerializedName("Buying")
        String buying;

        //if Path (/v3) not included 
        @SerializedName("Alış")
        String _buying;

       // else.. 
 }

interface DovizApi{
        @GET("/v3/today.json")
        fun getEnDoviz(): Call<Doviz>
}
Call<Doviz> call = dovizApi.getDoviz();
call.enqueue(new Callback<Doviz>(){
            @Override
            public void onResponse(Call<Doviz> call,Response<Doviz>response){
                Doviz doviz = response.body();
                CurrencyInfo info = doviz.getUsd();
                System.out.println(info.getBuying());
            }
..
}

效果不错。

发生了什么事?

  • API 响应的根是一个 JSONObject 而不是 JSONArray。
  • API URL.
  • 中缺少 v3

解决方案

更新界面

public interface DovizApi {
    @GET("v3/today.json")
    Call<HashMap<String, Object>> getDoviz();
}

更新响应模型(Doviz)

public class Doviz {
   @SerializedName("Buying")
   public String buying;

   // Similarly you can add other keys here
}

更新改造调用

Call<HashMap<String, Object>> call = dovizApi.getDoviz();
call.enqueue(new Callback<HashMap<String, Object>>() {

        @Override
        public void onResponse(Call<HashMap<String, Object>> call, Response<HashMap<String, Object>> response) {
            HashMap<String, Object> responseModel = response.body();

            // Iterate all the currencies
            for (Map.Entry<String, Object> entry : responseModel.entrySet())
                if(entry.getValue() instanceof LinkedTreeMap) { // Since the first element is of type String i.e. "Update_Date"
                    Doviz doviz = new Gson().fromJson(new Gson().toJson(((LinkedTreeMap<String, Object>) entry.getValue())), Doviz.class);
                    System.out.println("Currency = " + entry.getKey() +
                                     ", Buying = " + doviz.buying);
                }
        }

        @Override
        public void onFailure(Call<HashMap<String, Object>> call, Throwable t) {
            System.out.println(t.fillInStackTrace());
        }
    });