java - 使用 gson 反序列化 JSON 对象数组时遇到问题

标签 java android json wordpress gson

我正在编写一个 Android 阅读器应用程序,它使用 wordpress REST API 从 wordpress.com 网站提取内容,该 API 返回我要反序列化为应用程序中定义的 Article 对象的 JSON 对象。以下代码可以正确获取单个帖子的数据:

    private class getOne extends AsyncTask <Void, Void, JSONObject> {
    private static final String url = "https://public-api.wordpress.com/rest/v1/sites/drewmore4.wordpress.com/posts/slug:good-one";
    @Override
    protected JSONObject doInBackground(Void... params) {
        HttpClient httpclient = new DefaultHttpClient();
        HttpGet httpget = new HttpGet(url);
        httpget.addHeader("accept", "application/json");

        HttpResponse response;
        JSONObject object = new JSONObject();
        String resprint = new String();

        try {
            response = httpclient.execute(httpget);
            // Get the response entity
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                // get entity contents and convert it to string
                InputStream instream = entity.getContent();
                String result= convertStreamToString(instream);
                resprint = result;
                // construct a JSON object with result
                object=new JSONObject(result);
                // Closing the input stream will trigger connection release
                instream.close();
            }
        } 
        catch (ClientProtocolException e) {System.out.println("CPE"); e.printStackTrace();} 
        catch (IOException e) {System.out.println("IOE"); e.printStackTrace();} 
        catch (JSONException e) { System.out.println("JSONe"); e.printStackTrace();}

        return object;
    }
    @Override
    protected void onPostExecute (JSONObject object){
        System.out.println("POSTStexxx");
        Gson gson = new Gson();


        Article a = gson.fromJson(object.toString(), Article.class);
        System.out.println("XXCONTENT: " + a.content);

        System.out.println(a.ID);
        System.out.println(a.title);
        System.out.println(a.author.name);
    //  System.out.println(a.attachments.URL);

        WebView wv = (WebView)findViewById(R.id.mainview);

        wv.loadDataWithBaseURL(url, a.content, "text/html", "UTF-8", null);
        wv.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);


    }

}

println 语句显示预期结果,确认对象已正确反序列化。以下代码应该从网站上的所有帖子获取数据,但无法正常工作:

private class getAll extends AsyncTask <Void, Void, JSONObject> {
    private static final String url = "https://public-api.wordpress.com/rest/v1/sites/drewmore4.wordpress.com/posts/";
    @Override
    protected JSONObject doInBackground(Void... params) {

         //set up client and prepare request object to accept a json object
        HttpClient httpclient = new DefaultHttpClient();
        HttpGet httpget = new HttpGet(url);
        httpget.addHeader("accept", "application/json");
        JSONObject returned = new JSONObject();
        HttpResponse response;

        String resprint = new String();

        try {
            response = httpclient.execute(httpget);
            // Get the response entity
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                // get entity contents and convert it to string
                InputStream instream = entity.getContent();
                String result= convertStreamToString(instream);
                resprint = result;
                // construct a JSON object with result
                returned =new JSONObject(result);
                // Closing the input stream will trigger connection release
                instream.close();
            }
        } 
        catch (ClientProtocolException e) {System.out.println("CPE"); e.printStackTrace();} 
        catch (IOException e) {System.out.println("IOE"); e.printStackTrace();} 
        catch (JSONException e) { System.out.println("JSONe"); e.printStackTrace();}

       // stories = object;
        return returned;
    }

    @Override
    protected void onPostExecute (JSONObject returned){
        System.out.println("POSTStexxx");
        Gson gson = new Gson();

        PostsHandler ph = gson.fromJson(returned.toString(), PostsHandler.class);

        System.out.println("WAKAWAKA: " +  ph.posts.length);

    //  System.out.println("ARRAYLENGTH" + ja.length());
        ArrayList<Article> arts = new ArrayList<Article>();

        for (JSONObject o : ph.posts) {
            Article a = gson.fromJson(o.toString(), Article.class);
            System.out.println("TITLE: " + a.title);
                            System.out.println("TITLE: " + a.author);
            arts.add(a);
        }
        System.out.println("ARTICLEARRAY: " + arts.size());
        stories = arts;
        populateUI();

    }

此处返回的 JSON 对象包含一个 JSONArray 对象,该对象与单个帖子的查询返回的对象相同。程序运行,这里的 println 语句之一显示数组列表的大小是正确的(即与预期的帖子数量匹配),但每个对象的字段(标题、作者等)为空。我猜我没有正确处理数组,但我不知道我错在哪里。这是 Article 类,它映射每个帖子对象:

public class Article implements Serializable {

//  private static final long serialVersionUID = 1L;
    int ID;
    public String title;
    public String excerpt;
    public Author author;
    public String date;     
    public String URL;

    @SerializedName("featured_image")
    public String image;        
    public String content;
    //public String[] attachments;

    public Attachment attachments;
    public int comment_count;
    public int like_count;


}   


class Author {
long id;
String name;
String URL;
}

还有 PostsHandler 类,对所有帖子的查询的响应都映射到该类(我怀疑我的问题所在):

public class PostsHandler {
    int number;
JSONObject[] posts;

}

所有未用 @SerializedName 注释标记的字段与 JSONObject 中使用的字段相同。

我正在使用的 JSONObjects 可以在以下位置查看:

query for all posts

query for one post

最佳答案

GSON 在序列化/反序列化信息时支持“强”和“弱”类型的概念。强类型代表具有明确定义的接口(interface)的实际 Java bean 对象。弱类型表示数据(键/值)对的映射。目前您正在尝试混合搭配这两种模型,但这是行不通的。您要求 GSON 将数据反序列化为“强”类型 (PostsHandler)。但在该类中,您存储的是 GSON 的“弱”类型(JSONObjects)的实例。您应该选择(并坚持)一种处理模型。假设我们将使用强类型来反序列化数据。

这就是我实现PostsHandler的方式:

public PostsHandler implements Serializable {
    @SerializedName("found")
    private int number;

    @SerializedName("posts")
    private List<Article> articles

    // Constructors, getters, setters
}

还有onPostExecute:

@Override
protected void onPostExecute (JSONObject returned) {
    Gson gson = new Gson();
    PostsHandler ph = gson.fromJson(returned.toString(), PostsHandler.class);

    System.out.println("Article array length: " + ph.getArticles().size());
    stories = arts;
    populateUI();
}

关于java - 使用 gson 反序列化 JSON 对象数组时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15060127/

相关文章:

javascript - 复制对象到数组

java - 为 oauth token 请求传递授权 header

安卓工作室 : "SDK installation does not have the "Extras > Android Support Repository"installed"BUT IT HAS BEEN INSTALLED

java - 在与 Marklogic 交谈之前如何将排序查询添加到我的 StructuredQueryBuilder

json - 如何使一个空的 JSON 对象在 Postgres 中不唯一?

android - 使用自定义形状在 Canvas 上绘制位图

java - java中如何上传文件

java - 我如何编写一个函数,以 number(n) 作为输入并自动为类创建 (n) 个对象

Java ClassNotFoundException 与 Maven 依赖关系?

android - 父 NestedScrollView 禁用所有功能