java - tutorial - GSON lanzando “Se esperaba BEGIN_OBJECT pero fue BEGIN_ARRAY”?
object to jsonobject java (5)
Esta pregunta ya tiene una respuesta aquí:
Estoy tratando de analizar una cadena JSON como esta
[
{
"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"
}
]
en una lista de objetos.
List<ChannelSearchEnum> lcs = (List<ChannelSearchEnum>) new Gson().fromJson( jstring , ChannelSearchEnum.class);
Aquí hay una clase de objetos que estoy usando.
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;
}
}
Pero me tira con
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2
¿Alguna idea de cómo debería arreglarlo?
Alternativa podria ser
para hacer que tu respuesta parezca
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"
}
]
}
en lugar de
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"
}
]
CÓDIGO
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);
Después de esto será cualquier otro GSON Parsing
De acuerdo con la guía de usuario de GSON , usted no puede.
Limitaciones de colecciones
Puede serializar la colección de objetos arbitrarios, pero no puede deserializarla. Porque no hay forma de que el usuario indique el tipo del objeto resultante
El problema es que está solicitando un objeto de tipo ChannelSearchEnum
pero lo que realmente tiene es un objeto de tipo List<ChannelSearchEnum>
.
Puedes lograr esto con:
Type collectionType = new TypeToken<List<ChannelSearchEnum>>(){}.getType();
List<ChannelSearchEnum> lcs = (List<ChannelSearchEnum>) new Gson()
.fromJson( jstring , collectionType);
El problema es que le estás diciendo a Gson
que tienes un objeto de tu tipo. Usted no Tienes una matriz de objetos de tu tipo. No puedes simplemente intentar y lanzar el resultado de esa manera y esperar que funcione mágicamente;)
La guía del usuario para Gson
explica cómo lidiar con esto:
https://github.com/google/gson/blob/master/UserGuide.md
Esto funcionará:
ChannelSearchEnum[] enums = gson.fromJson(yourJson, ChannelSearchEnum[].class);
Pero esto es mejor:
Type collectionType = new TypeToken<Collection<ChannelSearchEnum>>(){}.getType();
Collection<ChannelSearchEnum> enums = gson.fromJson(yourJson, collectionType);
En mi caso la cadena JSON:
[{"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"}]
e imprimo "category" y "url_title" en recycleview
Clase de datos
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;
/ ** * Creado por Shweta.Chauhan el 13/07/16. * /
public interface RequestInterface {
@GET("facts/json/progress/all")
Call<List<Datum>> getJSON();
}
Adaptador de datos
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;
/ ** * Creado por Shweta.Chauhan el 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);
}
}
}
y finalmente 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());
}
});
}
}