JtecX JtecX - 2 months ago 34
Java Question

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

Learning how to use Retrofit in my Android App, getting following error:
Please help if you can. Thank you,

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


here is my code: Please help if your able too:

public void clickButton(View view){
button = (Button) findViewById(R.id.button);
drawDate = (TextView)findViewById(R.id.drawDate);

LotteryAPI.Factory.getIstance().getLottery().enqueue(new Callback<Lottery>() {
@Override
public void onResponse(Call<Lottery> call, Response<Lottery> response) {
Log.d(TAG, "getting Draw Date");
Log.d(TAG, "Draw Date is: " + response.body().getDrawDate());
String DRAW_DATE = response.body().getDrawDate();
drawDate.setText("DRAW_DATE");
Log.d(TAG, "done setting Draw Date");
}

@Override
public void onFailure(Call<Lottery> call, Throwable t) {
Log.e("Failed", t.getMessage());
Log.d(TAG, "At onFailure - Something Failed!!");
Log.d(TAG, "error is: " + t.getCause());

}
});
}


Here is my interface:

String BASE_URL = "https://data.ny.gov/resource/h6w8-42p9.json/";

@GET("?$$app_token=xxxxxxGtxKw3s6gurSxxxxxx")
Call<Lottery> getLottery();


class Factory {
public static LotteryAPI service;

public static LotteryAPI getIstance() {
if (service == null) {
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(BASE_URL).build();
service = retrofit.create(LotteryAPI.class);
return service;
} else {
return service;
}
}
}


Here is my POJO:

@Generated("org.jsonschema2pojo")
public class Lottery {

@SerializedName("draw_date")
@Expose
private String drawDate;
@SerializedName("mega_ball")
@Expose
private String megaBall;
@SerializedName("multiplier")
@Expose
private String multiplier;
@SerializedName("winning_numbers")
@Expose
private String winningNumbers;

/**
*
* @return
* The drawDate
*/
public String getDrawDate() {
return drawDate;
}

/**
*
* @param drawDate
* The draw_date
*/
public void setDrawDate(String drawDate) {
this.drawDate = drawDate;
}

/**
*
* @return
* The megaBall
*/
public String getMegaBall() {
return megaBall;
}

/**
*
* @param megaBall
* The mega_ball
*/
public void setMegaBall(String megaBall) {
this.megaBall = megaBall;
}

/**
*
* @return
* The multiplier
*/
public String getMultiplier() {
return multiplier;
}

/**
*
* @param multiplier
* The multiplier
*/
public void setMultiplier(String multiplier) {
this.multiplier = multiplier;
}

/**
*
* @return
* The winningNumbers
*/
public String getWinningNumbers() {
return winningNumbers;
}

/**
*
* @param winningNumbers
* The winning_numbers
*/
public void setWinningNumbers(String winningNumbers) {
this.winningNumbers = winningNumbers;
}

}

Answer

You should change the structure of POJO class structure, because as i can see your json string is an array which contain objects. You have to make to POJO classes:

class Lottery {
  private String draw_date, mega_ball, multiplier, winning_numbers;

public Lottery() {}

public String getDraw_date() {
    return draw_date;
}

public void setDraw_date(String draw_date) {
    this.draw_date = draw_date;
}

public String getWinning_numbers() {
    return winning_numbers;
}

public void setWinning_numbers(String winning_numbers) {
    this.winning_numbers = winning_numbers;
}

public String getMega_ball() {
    return mega_ball;
}

public void setMega_ball(String mega_ball) {
    this.mega_ball = mega_ball;
}

public String getMultiplier() {
    return multiplier;
}

public void setMultiplier(String multiplier) {
    this.multiplier = multiplier;
}

}

You also have to change the following line into LotteryAPI interface from

Call<Lottery> getLottery();

to

Call<List<Lottery>> getLottery();

Then inside onResponse() callback you should iterate through the LotteryObj list

 public void clickButton(View view){
    button = (Button) findViewById(R.id.button);
    drawDate = (TextView)findViewById(R.id.drawDate);

    LotteryAPI.Factory.getIstance().getLottery().enqueue(new Callback<List<Lottery>>() {
        @Override
        public void onResponse(Response<List<Lottery>> response, Retrofit retrofit) {
            Log.e(TAG, response.body()+"");
            for (Lottery lt : response.body()) {
                Log.e(TAG, lt.getDraw_date());
                Log.e(TAG, lt.getMega_ball());
                if (lt.getMultiplier() != null) Log.e(TAG, lt.getMultiplier());
                Log.e(TAG, lt.getWinning_numbers());
            }
                Log.d(TAG, "getting Draw Date");

// Log.d(TAG, "Draw Date is: " + response.body().getDrawDate()); // String DRAW_DATE = response.body().getDrawDate(); drawDate.setText("DRAW_DATE"); Log.d(TAG, "done setting Draw Date"); }

        @Override
        public void onFailure(Throwable t) {
            Log.e("Failed",  t.getMessage());
            Log.d(TAG, "At onFailure - Something Failed!!");
            Log.d(TAG, "error is: " + t.getCause());
        }
    });
}