简体   繁体   English

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

[英]Trouble deserializing an array of JSON objects using gson

I'm writing an android reader app that pulls content from a wordpress.com site using the wordpress REST API, which returns JSON objects that I am deserializing into Article objects that are defined in the app. 我正在编写一个Android阅读器应用程序,该应用程序使用wordpress REST API从wordpress.com网站提取内容,该API将我反序列化的JSON对象返回到该应用程序中定义的Article对象。 The following code, which gets data for a single post, works correctly: 以下代码(可获取单个帖子的数据)可以正常工作:

    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);


    }

}

The println statements show the expected results, confirming that the object has been deserialized properly. println语句显示预期结果,确认该对象已正确反序列化。 The following code, which should get data from all posts on the site, is not working properly: 以下代码应从网站上的所有帖子中获取数据,但无法正常运行:

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();

    }

The JSON object returned here contains a JSONArray of objects identical to the one returned by a query for a single post. 这里返回的JSON对象包含一个JSONArray对象,该对象与单个帖子的查询返回的对象相同。 The program runs, and one of the println statements here shows that the size of the arraylist is correct (ie matches the expected number of posts), but the fields for each object (title, author, etc) are null. 程序运行,这里的println语句之一表明arraylist的大小正确(即与预期的帖子数匹配),但是每个对象(标题,作者等)的字段为空。 I'm guessing I'm not treating the array properly, but I don't know where I'm erring. 我猜我没有正确地处理数组,但是我不知道在哪里出错。 Here is the Article class, which maps each post object: 这是Article类,它映射每个post对象:

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;
}

And the PostsHandler class, to which the response to the query for all posts is mapped (and where I suspect my problem is): 还有PostsHandler类,所有帖子的查询响应都映射到该类(我怀疑我的问题所在):

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

}

All fields not marked with the @SerializedName annotation are identical to the ones used in the JSONObjects. 所有未标记@SerializedName注释的字段均与JSONObjects中使用的字段相同。

The JSONObjects I'm working with can be seen at: 我正在使用的JSONObjects可以在以下位置看到:

query for all posts 查询所有帖子

query for one post 查询一个帖子

GSON supports the concept of 'strong' and 'weak' typing when serializing/deserializing information. 当对信息进行序列化/反序列化时,GSON支持“强”和“弱”类型的概念。 Strong types represent actual Java bean objects with a well defined interface. 强类型表示具有良好定义的接口的实际Java bean对象。 Weak types represent maps of data (key/value) pairs. 弱类型表示数据(键/值)对的映射。 Currently you are trying to mix and match both models, which doesn't work. 当前,您正在尝试混合和匹配这两种模型,这是行不通的。 You ask GSON to deserialize your data into a 'strong' type ( PostsHandler ). 您要求GSON将数据反序列化为“强”类型( PostsHandler )。 But inside that class you are storing instances of GSON's 'weak' type (the JSONObjects ). 但是在该类中,您存储的是GSON的“弱”类型( JSONObjects )的实例。 You should pick (and stick) with one processing model. 您应该选择(并坚持)一种处理模型。 Let's assume we are going to use strong types to deserialize the data. 假设我们将使用强类型对数据进行反序列化。

This is how I would implement the PostsHandler : 这就是我实现PostsHandler

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

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

    // Constructors, getters, setters
}

And the onPostExecute : 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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM