使用gson反序列化JSON对象的数组问题

问题描述:

我正在写一个android reader应用程序,它使用wordpress REST API从wordpress.com网站提取内容,该API将返回JSON对象,并将其反序列化为在应用程序。下面的代码,这对于单篇文章获取数据,正常工作:使用gson反序列化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语句显示数组列表的大小是正确的(即匹配期望的帖子数量),但是每个对象(标题,作者等)的字段为空。我猜我没有正确对待阵列,但我不知道我在哪里犯错。下面是文章类,其中每个岗位对象映射:

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注释标记的字段与JSONObjects中使用的字段相同。

query for all posts

query for one post

GSON序列化/反序列化信息时,支持 '强' 和 '弱' 打字的概念:

我工作的一个JSONObjects可以看出。强类型表示具有明确界面的实际Java bean对象。弱类型表示数据(键/值)对的映射。目前您正在尝试混合搭配两种模式,但这种模式无效。您要求GSON将您的数据反序列化为“强”类型(PostsHandler)。但是在这个类中,你存储了GSON'weak'类型的实例(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(); 
} 
+0

美丽的,完美的。感谢您的解释,我只是熟悉gson,这真的有所帮助。 – drewmoore 2013-02-25 05:03:50

+0

没问题,与学习过程祝你好运。 Gson是一个很好的图书馆。 – Perception 2013-02-25 05:07:57

+0

是的,它已经很容易学习迄今为止,除了一对夫妇打嗝。说到这,我有一个另一个问题:(http://stackoverflow.com/questions/15060514/deserializing-a-json-object-with-multiple-items-inside-it)。我想知道这是否是一个我应该使用弱打字的例子? – drewmoore 2013-02-25 05:11:25