GSON throwing "Expected BEGIN_OBJECT but was BEGIN_ARRAY"? GSON throwing "Expected BEGIN_OBJECT but was BEGIN_ARRAY"? java java

GSON throwing "Expected BEGIN_OBJECT but was BEGIN_ARRAY"?


The problem is you're telling Gson you have an object of your type. You don't. You have an array of objects of your type. You can't just try and cast the result like that and expect it to magically work ;)

The User guide for Gson Explains how to deal with this:

https://github.com/google/gson/blob/master/UserGuide.md

This will work:

ChannelSearchEnum[] enums = gson.fromJson(yourJson, ChannelSearchEnum[].class);

But this is better:

Type collectionType = new TypeToken<Collection<ChannelSearchEnum>>(){}.getType();Collection<ChannelSearchEnum> enums = gson.fromJson(yourJson, collectionType);


The problem is that you are asking for an object of type ChannelSearchEnum but what you actually have is an object of type List<ChannelSearchEnum>.

You can achieve this with:

Type collectionType = new TypeToken<List<ChannelSearchEnum>>(){}.getType();List<ChannelSearchEnum> lcs = (List<ChannelSearchEnum>) new Gson()               .fromJson( jstring , collectionType);


In my case JSON string:

[{"category":"College Affordability",  "uid":"150151",  "body":"Ended more than $60 billion in wasteful subsidies for big banks and used the savings to put the cost of college within reach for more families.",  "url":"http:\/\/www.whitehouse.gov\/economy\/middle-class\/helping middle-class-families-pay-for-college",  "url_title":"ending subsidies for student loan lenders",  "type":"Progress",  "path":"node\/150385"}]

and I print "category" and "url_title" in recycleview

Datum.class

import com.google.gson.annotations.Expose;import com.google.gson.annotations.SerializedName;public class Datum {@SerializedName("category")@Exposeprivate String category;@SerializedName("uid")@Exposeprivate String uid;@SerializedName("url_title")@Exposeprivate String urlTitle;/** * @return The category */public String getCategory() {    return category;}/** * @param category The category */public void setCategory(String category) {    this.category = category;}/** * @return The uid */public String getUid() {    return uid;}/** * @param uid The uid */public void setUid(String uid) {    this.uid = uid;}/** * @return The urlTitle */public String getUrlTitle() {    return urlTitle;}/** * @param urlTitle The url_title */public void setUrlTitle(String urlTitle) {    this.urlTitle = urlTitle;}}

RequestInterface

import java.util.List;import retrofit2.Call;import retrofit2.http.GET;/** * Created by Shweta.Chauhan on 13/07/16. */public interface RequestInterface {   @GET("facts/json/progress/all")   Call<List<Datum>> getJSON();}

DataAdapter

import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * Created by Shweta.Chauhan on 13/07/16. */public class DataAdapter extends RecyclerView.Adapter<DataAdapter.MyViewHolder>{private Context context;private List<Datum> dataList;public DataAdapter(Context context, List<Datum> dataList) {    this.context = context;    this.dataList = dataList;}@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {    View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.data,parent,false);    return new MyViewHolder(view);}@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) {    holder.categoryTV.setText(dataList.get(position).getCategory());    holder.urltitleTV.setText(dataList.get(position).getUrlTitle());}@Overridepublic int getItemCount() {    return dataList.size();}public class MyViewHolder extends RecyclerView.ViewHolder{    public TextView categoryTV, urltitleTV;    public MyViewHolder(View itemView) {        super(itemView);        categoryTV = (TextView) itemView.findViewById(R.id.txt_category);        urltitleTV = (TextView)     itemView.findViewById(R.id.txt_urltitle);    }}}

and finally MainActivity.java

import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.Log;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import retrofit2.Call;import retrofit2.Callback;import retrofit2.Response;import retrofit2.Retrofit;import retrofit2.converter.gson.GsonConverterFactory;public class MainActivity extends AppCompatActivity {private RecyclerView recyclerView;private DataAdapter dataAdapter;private List<Datum> dataArrayList;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    initViews();}private void initViews(){    recyclerView=(RecyclerView) findViewById(R.id.recycler_view);    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));    loadJSON();}private void loadJSON(){    dataArrayList = new ArrayList<>();    Retrofit retrofit=new Retrofit.Builder().baseUrl("https://www.whitehouse.gov/").addConverterFactory(GsonConverterFactory.create()).build();    RequestInterface requestInterface=retrofit.create(RequestInterface.class);    Call<List<Datum>> call= requestInterface.getJSON();    call.enqueue(new Callback<List<Datum>>() {        @Override        public void onResponse(Call<List<Datum>> call, Response<List<Datum>> response) {            dataArrayList = response.body();            dataAdapter=new DataAdapter(getApplicationContext(),dataArrayList);            recyclerView.setAdapter(dataAdapter);        }        @Override        public void onFailure(Call<List<Datum>> call, Throwable t) {            Log.e("Error",t.getMessage());        }    });}}