tutorial java android gson

java - tutorial - GSON lanzando “Se esperaba BEGIN_OBJECT pero fue BEGIN_ARRAY”?



object to jsonobject java (5)

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()); } }); } }