Java “格森投掷”;应为BEGIN_对象,但为BEGIN_数组;?
我正在尝试解析一个JSON字符串,就像这样Java “格森投掷”;应为BEGIN_对象,但为BEGIN_数组;?,java,android,gson,Java,Android,Gson,我正在尝试解析一个JSON字符串,就像这样 [ { "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
[
{
"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);
但这让我很沮丧
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2
你知道我该如何修复它吗?问题是你告诉Gson你有一个你自己类型的对象。你没有。您有一个类型的对象数组。你不能只是试着把结果变成那样,然后期待它神奇地工作;)
Gson
的用户指南解释了如何处理此问题:
这将有助于:
ChannelSearchEnum[] enums = gson.fromJson(yourJson, ChannelSearchEnum[].class);
但这更好:
Type collectionType = new TypeToken<Collection<ChannelSearchEnum>>(){}.getType();
Collection<ChannelSearchEnum> enums = gson.fromJson(yourJson, collectionType);
Type collectionType=new-TypeToken(){}.getType();
Collection enums=gson.fromJson(yourJson,collectionType);
根据,您不能
收藏限制
可以序列化任意对象的集合,但不能从中反序列化。因为用户无法指示结果对象的类型
问题是,您请求的对象类型为
ChannelSearchEnum
,但实际拥有的对象类型为List
您可以通过以下方式实现这一点:
Type collectionType = new TypeToken<List<ChannelSearchEnum>>(){}.getType();
List<ChannelSearchEnum> lcs = (List<ChannelSearchEnum>) new Gson()
.fromJson( jstring , collectionType);
Type collectionType=new-TypeToken(){}.getType();
列表lcs=(列表)新Gson()
.fromJson(jstring,collectionType);
备选方案可能是
让你的回答看起来像
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"
}
]
}
[
{
"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"
}
]
而不是
服务器响应
{"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"
}
]
}
[
{
"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);
在此之后,在我的JSON字符串中,它将只是任何其他的
GSON解析:
[{"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\u标题”
基准类
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;
}
}
请求接口
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
/**
* Created by Shweta.Chauhan on 13/07/16.
*/
public interface RequestInterface {
@GET("facts/json/progress/all")
Call<List<Datum>> getJSON();
}
import java.util.List;
2.电话;;
导入文件2.http.GET;
/**
*由Shweta.Chauhan于2016年7月13日创作。
*/
公共接口请求接口{
@获取(“事实/json/progress/all”)
调用getJSON();
}
数据适配器
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;
/**
* Created by Shweta.Chauhan on 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);
}
}
}
导入android.content.Context;
导入android.support.v7.widget.RecyclerView;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.TextView;
导入java.util.ArrayList;
导入java.util.List;
/**
*由Shweta.Chauhan于2016年7月13日创作。
*/
公共类DataAdapter扩展了RecyclerView.Adapter{
私人语境;
私有列表数据列表;
公共数据适配器(上下文上下文,列表数据列表){
this.context=上下文;
this.dataList=dataList;
}
@凌驾
公共MyViewHolder onCreateViewHolder(视图组父级,int-viewType){
View=LayoutInflater.from(parent.getContext()).flate(R.layout.data,parent,false);
返回新的MyViewHolder(视图);
}
@凌驾
公共无效onBindViewHolder(MyViewHolder,int位置){
holder.categoryTV.setText(dataList.get(position.getCategory());
holder.urltitleTV.setText(dataList.get(position.getUrlTitle());
}
@凌驾
public int getItemCount(){
返回dataList.size();
}
公共类MyViewHolder扩展了RecyclerView.ViewHolder{
公共文本视图分类电视,urltitleTV;
公共MyViewHolder(查看项目视图){
超级(项目视图);
categoryTV=(TextView)itemView.findViewById(R.id.txt\u category);
urltitleTV=(TextView)itemView.findViewById(R.id.txt\u 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());
}
});
}
}
导入android.support.v7.app.app活动;
导入android.os.Bundle;
导入android.support.v7.widget.LinearLayoutManager;
导入android.support.v7.widget.RecyclerView;
导入android.util.Log;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
2.电话;;
2.回拨;
2.回应;;
进口改装2.改装;
进口改装2.converter.gson.GsonConverterFactory;
公共类MainActivity扩展了AppCompatActivity{
私人回收站;
专用数据适配器;
私有列表dataArrayList;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
私有void initViews(){
recyclerView=(recyclerView)findViewById(R.id.recycler\u视图);
setLayoutManager(新的LinearLayoutManager(getApplicationContext());
loadJSON();
}
私有void loadJSON(){
dataArrayList=新的ArrayList();
改装改装=新改装.Builder().baseUrl(“https://www.whitehouse.gov/).addConverterFactory(GsonConverterFactory.create()).build();
RequestInterface RequestInterface=reformation.create(RequestInterface.class);
Call Call=requestInterface.getJSON();
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
dataArrayList=response.body();
dataAdapter=新的dataAdapter(getApplicationContext(),dataArrayList);
recyclerView.setAdapter(dataAdapter);
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.e(“Error”,t.getMessage());
}
});
}
}
您需要让Gson知道您的其他回复类型,如下所示
import com.google.common.reflect.TypeToken;
import java.lang.reflect.Type;
Type collectionType = new TypeToken<List<UserSite>>(){}.getType();
List<UserSite> userSites = gson.fromJson( response.getBody() , collectionType);
import com.google.common.reflect.TypeToken;
导入java.lang.reflect.Type;
Type collectionType=new-TypeToken(){}.getType();
List userSites=gson.fromJson(response.getBody(),collectionType);
我不确定这是否是使用GSON的最佳方式,但对我来说很有效。您可以在main活动
上使用类似的功能:
public void readJson() {
dataArrayList = new ArrayList<>();
String json = "[\n" + IOHelper.getData(this) + "\n]\n";
Log.d(TAG, json);
try{
JSONArray channelSearchEnums = new JSONArray(json);
for(int i=0; i< channelSearchEnums.length(); i++)
{
JSONObject enum = channelSearchEnums.getJSONObject(i);
ChannelSearchEnum channel = new ChannelSearchEnum(
enum.getString("updated_at"), enum.getString("fetched_at"),
enum.getString("description"), enum.getString("language"),
enum.getString("title"), enum.getString("url"),
enum.getString("icon_url"), enum.getString("logo_url"),
enum.getString("id"), enum.getString("modified"))
dataArrayList.add(channel);
}
//The code and place you want to show your data
}catch (Exception e)
{
Log.d(TAG, e.getLocalizedMessage());
}
}
如果您想了解更多有关这方面的信息,您可以看到,我在那里获得了readJson()
;在那里我得到了getData()
的代码,这看起来像一个Json数组列表。因此最好使用ArrayList
来处理数据。在api端点中添加如下数组列表
@GET("places/")
Call<ArrayList<Place>> getNearbyPlaces(@Query("latitude") String latitude, @Query("longitude") String longitude);
@GET(“places/”)
调用getNearbyPlaces(@Query(“纬度”)字符串纬度,@Query(“经度”)字符串经度);
Kotlin:
var list=ArrayList<Your class name>()
val listresult: Array<YOUR CLASS NAME> = Gson().fromJson(
YOUR JSON RESPONSE IN STRING,
Array<Your class name>:: class.java)
list.addAll(listresult)
var list=ArrayList()
瓦利斯
public ChannelSearchEnum[] getChannelSearchEnum(Response response) {
return response.as(ChannelSearchEnum[].class, ObjectMapperType.GSON);
}
define globle
private List<DataResponse> dataResponses = new ArrayList<>();