2012-03-07 248 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()); 
     } 
    }); 
} 
} 
相關問題