2012-03-07 247 views
202

我试图解析像这样的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" 
    } 
] 

一个JSON字符串对象的列表。

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,你会发现它是有效的。 – 2012-03-07 09:39:50

+0

@Soni - nope,删除了“[”和“]”,但仍然一样。猜猜它可能更多,因为我拥有的字符串包含多个对象,而不仅仅是一个。 – 2012-03-07 09:41:12

+0

你的'jstring'看起来像你在你的代码中提到的那样?可能确实是 – 2016-01-18 23:49:18

回答

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 2012-03-07 09:47:31

+3

+1 TypoToken >' - 当你有Collection(子类)和/或Iterables时,不要使用数组。 – 2012-03-07 09:54:41

+0

你认为这是解析所选obj /数组的正确方法吗?帮助http:// stackoverflow。com/questions/18140830/gson-throwing-expected-expected-a-name-but-was-number-at-line-1-column-8 – 2013-08-09 06:05:27

6

根据GSON User guide,你不能。

类别限制

可以序列化任意对象的集合,但不能从它反序列化。因为没有办法为用户指示生成的对象

+5

他没有一个任意对象的集合,他有*一个特定*类型的对象的集合,'Gson'实际上很乐意处理 – 2012-03-07 09:49:05

+0

,我开始时就像你一样用TypeToken写回答,但是由于通用类型不是在运行时嵌入的,我没有看到如何可能工作。 (虽然我还没有测试过)。 – njzk2 2012-03-07 13:36:06

31

的问题的类型是你所要求的channelSearchEnum类型的对象,但实际上你是什么List<channelSearchEnum>类型的对象。

你可以做到这一点:

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

这是什么样的“类型”?要导入什么? – 2015-04-28 04:43:36

+4

@ S.Matthew_English最有可能'java.lang.reflect.Type' – 2015-04-28 07:39:42

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" 
    } 
] 

CODE

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格式,该怎么办?我正在使用volley的gson请求来设置我的模型类。怎么做?谢谢 – 2015-08-14 11:38:00

+0

@KaveeshKanwal尝试此线程提供的其他解决方案,除此之外我不知道 – DeltaCap 2015-08-17 17:22:50

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"}] 

我打印recycleview “类别” 和 “url_title”

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()); 
     } 
    }); 
} 
} 
相关问题