AndRoid Studio java.lang.IllegalStateException:应为BEGIN_数组,但在第1行第2列路径处为BEGIN_对象$

AndRoid Studio java.lang.IllegalStateException:应为BEGIN_数组,但在第1行第2列路径处为BEGIN_对象$,java,android,retrofit,retrofit2,Java,Android,Retrofit,Retrofit2,我知道这不是关于这个错误的第一个问题。我到处寻找答案,但找不到答案。当我运行代码时,我得到了这个异常 java.lang.IllegalStateException:应为BEGIN\u数组,但在第1行第2列路径$处为BEGIN\u对象。 主要活动 public class MainActivity extends AppCompatActivity { ArrayList<Doviz> dovizs; @Override protected void onC

我知道这不是关于这个错误的第一个问题。我到处寻找答案,但找不到答案。当我运行代码时,我得到了这个异常

java.lang.IllegalStateException:应为BEGIN\u数组,但在第1行第2列路径$处为BEGIN\u对象。

主要活动

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());
            }
        });
    }
}
接口

public interface DovizApi {
    @GET("today.json")
    Call<List<Doviz>> getDoviz();
}
public interface DovizApi {
    @GET("v3/today.json")
    Call<HashMap<String, Object>> getDoviz();
}
公共接口DovizApi{
@获取(“today.json”)
调用getDoviz();
}
我使用的列表

我已经处理这件事好几天了。我希望我们能解决这个问题

  • 类型
  • Json如下所示

    {
       "Update_Date":"2021-05-12 16:00:01",
       "USD":{
          "Buying":"8,3681",
          "Type":"Currency",
          "Selling":"8,3735",
          "Change":"%1,13"
       },
       ...
    }
    
    它不是
    USD
    是json中的关键之一

    因此,
    Call
    应更改为
    Call

  • DTO(Doviz)
  • 您可能想购买
    美元的
    价值。
    您的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.. 
     }
    
    
    接口DovizApi{
    @获取(“/v3/today.json”)
    fun getEnDoviz():调用
    }
    
    Call Call=dovizApi.getDoviz();
    call.enqueue(新回调(){
    @凌驾
    公共void onResponse(Call Call,Responseresponse){
    Doviz Doviz=response.body();
    CurrencyInfo=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();
    }
    
    更新改装呼叫

    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());
            }
        });
    
    Call Call=dovizApi.getDoviz();
    call.enqueue(新回调(){
    @凌驾
    公共void onResponse(调用、响应){
    HashMap responseModel=response.body();
    //迭代所有货币
    对于(Map.Entry:responseModel.entrySet())
    如果(entry.getValue()instanceof LinkedTreeMap){//,因为第一个元素的类型为String,即“Update_Date”
    Doviz Doviz=new Gson().fromJson(new Gson().toJson(((LinkedTreeMap)entry.getValue()),Doviz.class);
    System.out.println(“Currency=“+entry.getKey()+
    “,Buying=“+doviz.Buying”);
    }
    }
    @凌驾
    失败时公共无效(调用调用,可丢弃的t){
    System.out.println(t.fillInStackTrace());
    }
    });
    
    此错误行第1列第2列路径$是因为您的API重新检查了您的API。当我检查API时,我收到另一个错误。“List responseList=response.body();”此部分不起作用。它说“”java.lang.ClassCastException:com.example.parsingjson.Doviz不能强制转换为java.util.List“”
    List
    应该更改为
    Doviz
    。它不是ListI在下面的答案中添加了执行代码。我尝试了,但得到了此异常。“java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'java.util.Set java.util.HashMap.entrySet()"我能做什么?@doğukanğiftçi我已经在验证后更新了答案。它现在应该可以工作了。请更新解决方案部分中提到的代码库。您是最好的。非常感谢您,它现在可以工作了。但我想问您个人问题。为什么我们使用HashMap?我们可以使用什么来代替HashMap?此代码“Doviz d”是什么意思oviz=new Gson().fromJson(new Gson().toJson((LinkedTreeMap)entry.getValue()),Doviz.class);“”。你是如何学会这些的?是的,问题已经解决了,但我不明白它是怎么发生的。我仍然不能自己编写这段代码,我该如何学习?再次感谢你,祝你有一个健康的日子。@Doğukanïiftç我很高兴听到问题已经解决。使用HashMap的原因是因为你的回答是自定义键(而不是固定键)对于货币。你可以通过挖掘Gson库了解更多信息。谢谢你的帮助,但我需要你的帮助,因为我不知道我们到底在做什么。我必须在recyclerview中使用这个变量(货币名称和购买)。我如何使用它?我脑子里的一切都很混乱。数组列表,列表,哈希映射。。。
    public interface DovizApi {
        @GET("v3/today.json")
        Call<HashMap<String, Object>> getDoviz();
    }
    
    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());
            }
        });