简体   繁体   中英

RETROFIT 2 Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2

I am new to retrofit and getting this error(Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2) on simple HTTP get request. Here is the code.Help me..`

Main Activity

private ListView listView;

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

    listView = (ListView) findViewById(R.id.pagination_list);


    Retrofit.Builder builder = new Retrofit.Builder()
            .baseUrl("https://www.googleapis.com/books/v1/")
            .addConverterFactory(GsonConverterFactory.create());

    Retrofit retrofit = builder.build();

    String apiKey = getResources().getString(R.string.API_KEY);

    GitHubClient client = retrofit.create(GitHubClient.class);
    Call<List<Volumes>> call = client.reposForUser(apiKey);

    call.enqueue(new Callback<List<Volumes>>() {
        @Override
        public void onResponse(Call<List<Volumes>> call, Response<List<Volumes>> response) {
            List<Volumes> repos = response.body();
            int responseCode = response.code();
            Log.v("Volumeinfo", "onResponse: "+ responseCode);

            listView.setAdapter(new GitHubRepoAdapter(MainActivity.this, repos));
        }

        @Override
        public void onFailure(Call<List<Volumes>> call, Throwable t) {

            Log.v("Volumeinfo", "onResponse: "+ t.getMessage());
            Toast.makeText(MainActivity.this, t.getMessage()+"error :(", Toast.LENGTH_LONG).show();
        }
    });
}

Interface

{

@GET("volumes?q=Android+intitle")
Call<List<Volumes>> reposForUser(@Query("key")String ApiKey );
}




 public class Volumes {




 @SerializedName("title")
 @Expose
 private String title;


public String getTitle() {
    return title;
}

}

Adapter

private Context context;
private List<Volumes> values;

public GitHubRepoAdapter(Context context, List<Volumes> values) {
    super(context, R.layout.list_item_pagination, values);

    this.context = context;
    this.values = values;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;

    if (row == null) {
        LayoutInflater inflater =
                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(R.layout.list_item_pagination, parent, false);
    }

    TextView textView = (TextView) row.findViewById(R.id.list_item_pagination_text);

    Volumes item = values.get(position);
    String message = item.getTitle();
    textView.setText(message);

    return row;
}
}

Json

   {
  "kind": "books#volumes",
  "totalItems": 3395,
  "items": [
   {
  "kind": "books#volume",
   "id": "1igDDgAAQBAJ",
   "etag": "oS4LeBsRcfg",
   "selfLink": "https://www.googleapis.com/books/v1/volumes/1igDDgAAQBAJ",
    "volumeInfo": {
"title": "Android Programming",
"subtitle": "The Big Nerd Ranch Guide",
"authors": [
 "Bill Phillips",
 "Chris Stewart",
 "Kristin Marsicano"
],
"publisher": "Pearson Technology Group",
"publishedDate": "2017-01-30",
"description": "This is the eBook of the printed book and may not include 
",
"industryIdentifiers": [
 {
  "type": "ISBN_13",
  "identifier": "9780134706078"
 },
 {
  "type": "ISBN_10",
  "identifier": "0134706072"
 }
],
"readingModes": {
 "text": true,
 "image": true
},
"pageCount": 624,
"printType": "BOOK",
"categories": [
 "Computers"
 ],
"maturityRating": "NOT_MATURE",
"allowAnonLogging": true,
"contentVersion": "1.1.1.0.preview.3",
"panelizationSummary": {
 "containsEpubBubbles": false,
 "containsImageBubbles": false
    },
   "imageLinks": {
    "smallThumbnail": "http://books.google.com/books/content?  
 id=1igDDgAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
 "thumbnail": "http://books.google.com/books/content?
 id=1igDDgAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
  },
        "language": "en",
        "previewLink": "http://books.google.com/books?

Complete Json https://www.googleapis.com/books/v1/volumes?q=Android+intitle

Almost searched everywhere ..help will be really appreciated

The setup you have seems to have setup retrofit to parse json, so this answer assumes that too.

The error you're getting comes from Gson and if you look at it - Expected BEGIN_ARRAY but was BEGIN_OBJECT - it's telling you that while parsing the json it was expecting an array, but got an object.

The second part of the error is easy to understand. If you look at your json it starts with { which is an object and not an array (that would start with [ ). So why is it expecting an array?

For this you have to turn to your retrofit interface declaration. You say that your call will return a List<Volumes> (Gson can convert between json arrays and java lists). The problem is that the returned json is (as already explained) an object and not a list, so gson has trouble converting it to a list.

Looking further at your models, changing it to just return Volumes will not be enough and will result in further errors. You have to basically map directly your json to java objects (unless you want to use custom deserialisers which is quite unnecessary).

By mapping directly to java I mean that you'll have to come up with an object that represents the root json element, then one that represents the items (which can just be a list of objects) and so on.

Here's a great website that can help you out not only understanding what I meant but also generating the models for you based on your json. You paste the json in the field, make sure you have the right options selected - source type json, annotation style gson, etc. There's even plugins for android studio too.

Hope it helps

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