2012-03-07 8 views
202

Я пытаюсь разобрать строку JSON как этотGSON бросает «Ожидаемое BEGIN_OBJECT, но BEGIN_ARRAY»?

[ 
    { 
     "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 

Любые идеи, как я должен это исправить?

+10

@Soni - это неправильно. Если вы перейдете на jsonlint.org и скопируете/вставьте его JSON, вы увидите, что он действителен. –

+0

@ Сони - нет, удалены "[" и "]", но все равно. предположим, это может быть больше, потому что строка, которую я содержит, содержит несколько объектов, а не только одну. –

+0

Как выглядит ваша 'jstring', о которой вы указали в своем коде? –

ответ

227

Проблема в том, что вы говорите 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); 
+0

, вероятно, действительно. как массив объекта, тип сохраняется во время выполнения, поэтому gson знает, что искать. хорошая идея. – njzk2

+3

+1 для 'TypoToken >' - не используйте массивы, если у вас есть коллекция (подклассы) и/или Iterables. –

+0

Как вы думаете, это правильный метод для анализа выбранного объекта/массива? help http: // stackoverflow.com/questions/18140830/gson-throwing-expected-expected-a-name-but-was-number-at-line-1-column-8 –

6

в зависимости GSON User guide, вы не можете.

Коллекция Ограничение

сериализовать коллекцию произвольных объектов, но не десериализации от него. Потому что нет никакого способа для пользователя, чтобы указать тип результирующего объекта

+5

У него нет коллекции произвольных объектов, у него есть набор * одного конкретного * типа объекта, который 'Gson' будет счастливо иметь дело с –

+0

, я начал писать ответ с помощью TypeToken так же, как вы, но так как общий тип не внедрен во время выполнения, я не видел, как это может работать. (хотя я его не тестировал). – njzk2

31

Проблема заключается в том, что вы просите объект типа channelSearchEnum, но то, что вы на самом деле является объектом типа List<channelSearchEnum>.

Вы можете добиться этого с:

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

Какой тип 'Тип'? что импортировать? –

+4

@ S.Matthew_English скорее всего 'java.lang.reflect.Type' –

7

альтернатива может быть

, чтобы сделать ваш ответ выглядеть

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

+0

что делать, если я не могу изменить свой формат json? Я использую запрос gson volley для установки моего класса модели. Как это сделать? Спасибо –

+0

@KaveeshKanwal попробуйте другие решения, представленные в этой теме, кроме этого я понятия не имею – DeltaCap

15

В моем случае строка 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"}] 

и печатаю "категории" и "url_title" в recycleview

Datum.class

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; 

/** * Создано Shweta.Chauhan 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; 

/** * Создано Shweta.Chauhan на 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()); 
     } 
    }); 
} 
} 
Смежные вопросы