简体   繁体   中英

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

I know this is not first question about this error. I've searched for the answer in everywhere but i couldn't find the solve. when i run the code i get this exception;

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

Main 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;

}

Interface

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

the list i use https://finans.truncgil.com/v3/today.json

I have been dealing with this for days. I hope we can solve it

What's Happening?

  • The root of the API response is a JSONObject and not the JSONArray.
  • v3 is missing from the API URL.

Solution

Update Interface

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

Update Response Model(Doviz)

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

   // Similarly you can add other keys here
}

Update Retrofit Call

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

Check point

  1. Type

Json looks like below

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

It's not <List> and USD is one of key in json

so the Call<List<Doviz>> should change to Call<Doviz>

  1. DTO (Doviz)

You may want Buying value of USD . You're DTO(Doviz) should has property as another DTO like this

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

It worked well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM