Gson бросает "ожидаемый объект BEGIN, но был массив BEGIN"? [дубликат]
этот вопрос уже есть ответ здесь:
Почему Gson fromJson бросает JsonSyntaxException: ожидаемый BEGIN_OBJECT, но был BEGIN_ARRAY?
2 ответы
Я пытаюсь разобрать строку JSON, как этот
[
{
"updated_at":"2012-03-02 21:06:01",
"fetched_at":"2012-03-02 21:28:37.728840",
"description":null,
"language":null,
"title":"JOHN",
"url":"http://rus.JOHN.JOHN/rss.php",
"icon_url":null,
"logo_url":null,
"id":"4f4791da203d0c2d76000035",
"modified":"2012-03-02 23:28:58.840076"
},
{
"updated_at":"2012-03-02 14:07:44",
"fetched_at":"2012-03-02 21:28:37.033108",
"description":null,
"language":null,
"title":"PETER",
"url":"http://PETER.PETER.lv/rss.php",
"icon_url":null,
"logo_url":null,
"id":"4f476f61203d0c2d89000253",
"modified":"2012-03-02 23:28:57.928001"
}
]
в списке объектов.
List<ChannelSearchEnum> lcs = (List<ChannelSearchEnum>) new Gson().fromJson( jstring , ChannelSearchEnum.class);
вот класс объектов я с помощью.
import com.google.gson.annotations.SerializedName;
public class ChannelSearchEnum {
@SerializedName("updated_at")
private String updated_at;
@SerializedName("fetched_at")
private String fetched_at;
@SerializedName("description")
private String description;
@SerializedName("language")
private String language;
@SerializedName("title")
private String title;
@SerializedName("url")
private String url;
@SerializedName("icon_url")
private String icon_url;
@SerializedName("logo_url")
private String logo_url;
@SerializedName("id")
private String id;
@SerializedName("modified")
private String modified;
public final String get_Updated_at() {
return this.updated_at;
}
public final String get_Fetched_at() {
return this.fetched_at;
}
public final String get_Description() {
return this.description;
}
public final String get_Language() {
return this.language;
}
public final String get_Title() {
return this.title;
}
public final String get_Url() {
return this.url;
}
public final String get_Icon_url() {
return this.icon_url;
}
public final String get_Logo_url() {
return this.logo_url;
}
public final String get_Id() {
return this.id;
}
public final String get_Modified() {
return this.modified;
}
}
но он бросает меня с
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2
любые идеи, как я должен это исправить?
5 ответов:
проблема в том, что ты говоришь
Gsonу вас есть объект вашего типа. У вас есть массив объектов вашего типа. Вы не можете просто попробовать и бросить результат таким образом и ожидать, что он волшебным образом сработает;)руководство по эксплуатации
Gsonобъясняет, как с этим бороться:https://github.com/google/gson/blob/master/UserGuide.md
это будет работать:
ChannelSearchEnum[] enums = gson.fromJson(yourJson, ChannelSearchEnum[].class);но это лучше:
Type collectionType = new TypeToken<Collection<ChannelSearchEnum>>(){}.getType(); Collection<ChannelSearchEnum> enums = gson.fromJson(yourJson, collectionType);
проблема в том, что вы просите объект типа
ChannelSearchEnumно то, что вы на самом деле есть объект типаList<ChannelSearchEnum>.вы можете достичь этого с помощью:
Type collectionType = new TypeToken<List<ChannelSearchEnum>>(){}.getType(); List<ChannelSearchEnum> lcs = (List<ChannelSearchEnum>) new Gson() .fromJson( jstring , collectionType);
в моем случае строка JSON:
[{"category":"College Affordability", "uid":"150151", "body":"Ended more than 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"}]и я печатаю " category "и" url_title " в recycleview
Datum.класс
import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; public class Datum { @SerializedName("category") @Expose private String category; @SerializedName("uid") @Expose private String uid; @SerializedName("url_title") @Expose private 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;/** * Создано Шветой.Чаухан на 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;/** * Создано Шветой.Чаухан на 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; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.data,parent,false); return new MyViewHolder(view); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.categoryTV.setText(dataList.get(position).getCategory()); holder.urltitleTV.setText(dataList.get(position).getUrlTitle()); } @Override public 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); } } }и, наконец, 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; @Override protected 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()); } }); } }
альтернативный вариант
чтобы ваш ответ выглядел
myCustom_JSONResponse
{"master":[ { "updated_at":"2012-03-02 21:06:01", "fetched_at":"2012-03-02 21:28:37.728840", "description":null, "language":null, "title":"JOHN", "url":"http://rus.JOHN.JOHN/rss.php", "icon_url":null, "logo_url":null, "id":"4f4791da203d0c2d76000035", "modified":"2012-03-02 23:28:58.840076" }, { "updated_at":"2012-03-02 14:07:44", "fetched_at":"2012-03-02 21:28:37.033108", "description":null, "language":null, "title":"PETER", "url":"http://PETER.PETER.lv/rss.php", "icon_url":null, "logo_url":null, "id":"4f476f61203d0c2d89000253", "modified":"2012-03-02 23:28:57.928001" } ] }вместо
server_JSONResponse
[ { "updated_at":"2012-03-02 21:06:01", "fetched_at":"2012-03-02 21:28:37.728840", "description":null, "language":null, "title":"JOHN", "url":"http://rus.JOHN.JOHN/rss.php", "icon_url":null, "logo_url":null, "id":"4f4791da203d0c2d76000035", "modified":"2012-03-02 23:28:58.840076" }, { "updated_at":"2012-03-02 14:07:44", "fetched_at":"2012-03-02 21:28:37.033108", "description":null, "language":null, "title":"PETER", "url":"http://PETER.PETER.lv/rss.php", "icon_url":null, "logo_url":null, "id":"4f476f61203d0c2d89000253", "modified":"2012-03-02 23:28:57.928001" } ]код
String server_JSONResponse =.... // the string in which you are getting your JSON Response after hitting URL String myCustom_JSONResponse="";// in which we will keep our response after adding object element to it MyClass apiResponse = new MyClass(); myCustom_JSONResponse="{\"master\":"+server_JSONResponse+"}"; apiResponse = gson.fromJson(myCustom_JSONResponse, MyClass .class);после этого будет просто любой другой
GSON Parsing
по данным руководство пользователя GSON, вы не можете.
Ограничения Коллекций
может сериализовать коллекцию произвольных объектов, но не может десериализоваться из нее. Потому что нет никакого способа для пользователя, чтобы указать тип полученного объекта
Comments