【问题标题】:Deserialising nested JSON Response with GSON使用 GSON 反序列化嵌套的 JSON 响应
【发布时间】:2016-10-23 09:45:24
【问题描述】:

好吧,我是 GSON 的新手,我试图反序列化来自 Wordpress 博客的 JSON 响应。

这是 JSON 响应:

{
  "status": "ok",
  "count": 10,
  "pages": 484,
  "category": {
    "id": "",
    "slug": "",
    "title": "",
    "description": "",
    "parent": 0,
    "post_count": 4837
  },
  "posts": [{
    "id": "",
    "type": "",
    "slug": "",
    "url": "",
    "status": "",
    "title": "",
    "title_plain": "",
    "content": "",
    "excerpt": "",
    "date": "",
    "modified": "",
    "categories": [{
      "id": "",
      "slug": "",
      "title": "",
      "description": "",
      "parent": "",
      "post_count": ""
    }, {
      "id": "",
      "slug": "",
      "title": "",
      "description": "",
      "parent": "",
      "post_count": ""
    }, {
      "id": "",
      "slug": "",
      "title": "",
      "description": "",
      "parent": "",
      "post_count": ""
    }],
    "tags": [{
      "id": "",
      "slug": "",
      "title": "",
      "description": "",
      "post_count": ""
    }],
    "author": {
      "id": "",
      "slug": "",
      "name": "",
      "first_name": "",
      "last_name": "",
      "nickname": "",
      "url": "",
      "description": ""
    },
    "comments": [],
    "attachments": [{
      "id": "",
      "url": "",
      "slug": "",
      "title": "",
      "description": "",
      "caption": "",
      "parent": "",
      "mime_type": "",
      "images": {
        "full": {
          "url": "",
          "width": "",
          "height": ""
        },
        "thumbnail": {
          "url": "",
          "width": "",
          "height": ""
        },
        "medium": {
          "url": "",
          "width": "",
          "height": ""
        },
        "medium_large": {
          "url": "",
          "width": "",
          "height": ""
        },
        "large": {
          "url": "",
          "width": "",
          "height": ""
        },
        "tie-small": {
          "url": "",
          "width": "",
          "height": ""
        },
        "tie-medium": {
          "url": "",
          "width": "",
          "height": ""
        },
        "tie-large": {
          "url": "",
          "width": "",
          "height": ""
        },
        "slider": {
          "url": "",
          "width": "",
          "height": ""
        },
        "big-slider": {
          "url": "",
          "width": "",
          "height": ""
        }
      }
    }],
    "comment_count": 0,
    "comment_status": "",
    "thumbnail": "",
    "custom_fields": {
      "tie_sidebar_pos": [
        ""
      ],
      "tie_post_slider": [
        ""
      ]
    },
    "thumbnail_size": "",
    "thumbnail_images": {
      "full": {
        "url": "",
        "width": "",
        "height": ""
      },
      "thumbnail": {
        "url": "",
        "width": "",
        "height": ""
      },
      "medium": {
        "url": "",
        "width": "",
        "height": ""
      },
      "medium_large": {
        "url": "",
        "width": "",
        "height": ""
      },
      "large": {
        "url": "",
        "width": "",
        "height": ""
      },
      "tie-small": {
        "url": "",
        "width": "",
        "height": ""
      },
      "tie-medium": {
        "url": "",
        "width": "",
        "height": ""
      },
      "tie-large": {
        "url": "",
        "width": "",
        "height": ""
      },
      "slider": {
        "url": "",
        "width": "",
        "height": ""
      },
      "big-slider": {
        "url": "",
        "width": "",
        "height": ""
      }
    }
  }]
}

这是我的项目代码:

ItemObject.java

import com.google.gson.annotations.SerializedName;

public class ItemObject {

    @SerializedName("id")
    private String postID;
    @SerializedName("title")
    private String postTitle;
    @SerializedName("except")
    private String except;

    public ItemObject(String postID, String postTitle, String except) {

        this.postID = postID;
        this.postTitle = postTitle;
        this.except = except;
    }

    public String getpostID() {
        return postID;
    }
    public String getPostTitle() {
        return postTitle;
    }
    public String getExcept() {
        return except;
    }
}

RecyclerViewAdapter.java

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {

    private List<ItemObject> itemList;
    private Context context;

    public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
        this.itemList = itemList;
        this.context = context;
    }

    @Override
    public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {

        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
        RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
        return rcv;

    }

    @Override
    public void onBindViewHolder(RecyclerViewHolders holder, int position) {

        holder.postID.setText(itemList.get(position).getpostID());
        holder.postTitle.setText(itemList.get(position).getPostTitle());
        holder.contentExcept.setText(itemList.get(position).getExcept());

    }

    @Override
    public int getItemCount() {
        return this.itemList.size();
    }
}

RecyclerViewHolders.java

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{

    public TextView postID;
    public TextView postTitle;
    public TextView contentExcept;

    public RecyclerViewHolders(View itemView) {

        super(itemView);
        itemView.setOnClickListener(this);

        postID = (TextView)itemView.findViewById(R.id.post_id);
        postTitle = (TextView)itemView.findViewById(R.id.post_title);
        contentExcept = (TextView)itemView.findViewById(R.id.except);

    }

    @Override
    public void onClick(View view) {
    }
}

SimpleDividerItemDecoration.java

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;

    public SimpleDividerItemDecoration(Context context) {
        mDivider = ContextCompat.getDrawable(context, R.drawable.line_divider);
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
}

MainActivity.java

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private final String TAG = "MainActivity";
    private RecyclerView recyclerView;
    private LinearLayoutManager layoutManager;
    private RecyclerViewAdapter adapter;

    public static final String POST_TITLE = "post_title";
    public static final String EXCEPT = "except";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
        recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
        layoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(layoutManager);

        requestJsonObject();

        // Swipe Refresh Layout
        final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swifeRefresh);
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                requestJsonObject();
                mSwipeRefreshLayout.setRefreshing(false);
            }
        });
    }

    private void requestJsonObject(){

        RequestQueue queue = Volley.newRequestQueue(this);
        String url ="JSON URL";
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {

                Log.d(TAG, "Response " + response);
                GsonBuilder builder = new GsonBuilder();
                Gson mGson = builder.create();

                List<ItemObject> posts = new ArrayList<ItemObject>();
                posts = Arrays.asList(mGson.fromJson(response, ItemObject[].class));
                adapter = new RecyclerViewAdapter(MainActivity.this, posts);
                recyclerView.setAdapter(adapter);

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, "Error " + error.getMessage());
            }
        });
        queue.add(stringRequest);
    }
}

运行项目后,我从 logcat 收到此错误:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

任何帮助将不胜感激。 谢谢。

【问题讨论】:

  • 您需要一个拥有项目列表的对象
  • @Raghunandan 如何添加对象?
  • 您是否要显示posts 键下的数据?
  • @KNeerajLal 是的,正确。
  • { 表示一个 json 对象,在该对象下您有 "posts": [{ 的帖子列表。只需使用pojo.sodhanalibrary.com 为您的 json 生成 pojo,这对您来说会容易得多

标签: java android android-recyclerview gson android-json


【解决方案1】:

您应该创建适当的 POJO 结构来反序列化 api 响应。您可以使用this webiste,它是一个 json 到 java 解析器,并创建正确的 java 类结构来表示您的 json 响应。

【讨论】:

    【解决方案2】:

    您的代码的解决方法,

    JSONObject jObject = new JSONObject(response);
    
    // take the "post" key
    JSONArray responseArray = jObject.getJSONArray("posts");
    
    // deserialise the data
    Type type = new TypeToken<List<ItemObject>>(){}.getType();
    List<ItemObject> posts = new Gson().fromJson(responseArray.toString(), type);
    
    // bind the data
    adapter = new RecyclerViewAdapter(MainActivity.this, posts);
    recyclerView.setAdapter(adapter);
    

    实际解决方案,

    1. 转到 jsonschema2pojo 或 pojo.sodhanalibrary 并粘贴您 JSON 那里。

    2. 生成 POJO 类。

    3. 使用GSON反序列化如下,

      POJO object = new Gson().fromJson(respone , POJO.class);

    注意:ItemObject.java 中有错字。

    改变,

    @SerializedName("except")
    private String except;
    

    到,

    @SerializedName("excerpt")
    private String excerpt;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多