2017-07-24 37 views
-1

在你假設這個問題是基於它的標題的重複之前,我必須說我找不到任何解決方案我的具體問題。不過,如果您能建議一些鏈接,我將不勝感激!這就是說,我的問題是,我不斷收到以下GSON例外:使用GSON解析JSON數據到陣列時出錯

07-24 10:12:44.713 2540-2603/com.davenotdavid.dndheadlines W/System.err: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ 

我明白,我莫名其妙地傳遞一個JSON對象,而不是一個數組,但我不明白的是它是如何的不工作的基礎上,基本上有輔助方法來解析和使用OkHttpClient和GSON庫中的JSON數組中提取JSON數據,然後返回提取數據的列表返回給調用類以下的實用工具類:

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 

import java.lang.reflect.Type; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.List; 

import okhttp3.OkHttpClient; 
import okhttp3.Request; 
import okhttp3.Response; 

public class QueryUtils { 
    public static List<Article> fetchArticleData(String requestUrl) { 
     String jsonResponse = ""; 
     try { 
      OkHttpClient okHttpClient = new OkHttpClient(); 
      Request request = new Request.Builder() 
        .url(requestUrl) 
        .build(); 
      Response response = okHttpClient.newCall(request).execute(); 
      jsonResponse = response.body().string(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return extractDataFromJson(jsonResponse); 
    } 

    private static List<Article> extractDataFromJson(String jsonResponse) { 
     if (jsonResponse == null || jsonResponse.isEmpty()) { 
      return null; 
     } 

     List<Article> articlesList = new ArrayList<>(); 

     ArticleResponse[] articleResult = new ArticleResponse[0]; 
     try { 
      Gson gson = new Gson(); 
      Type collectionType = new TypeToken<Collection<ArticleResponse>>(){}.getType(); 

      // *** Exception is thrown here *** 
      Collection<ArticleResponse> enums = gson.fromJson(jsonResponse, collectionType); 

      articleResult = enums.toArray(new ArticleResponse[enums.size()]); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     if (articleResult.length != 0) { 
      for (int i = 0; i < articleResult.length; i++) { 
       ArticleResponse article = articleResult[i]; 
       articlesList.add(new Article(
         article.getTitle(), 
         article.getUrl(), 
         article.getUrlToImage(), 
         article.getPublishedAt())); 
      } 
     } 

     return articlesList; 
    } 
} 

正如你會注意到下面這行代碼引發了異常:

Collection<ArticleResponse> enums = gson.fromJson(jsonResponse, collectionType); 

這是我生成使用GsonFormat的ArticleResponse類:

public class ArticleResponse { 

    /** 
    * author : Annalee Newitz 
    * title : First glimpse of Steven Spielberg’s new movie, Ready Player One 
    * description : This trailer introduces us to a VR dystopia, and has the greatest soundtrack ever. 
    * url : https://arstechnica.com/the-multiverse/2017/07/first-glimpse-of-steven-spielbergs-new-movie-ready-player-one/ 
    * urlToImage : https://cdn.arstechnica.net/wp-content/uploads/2017/07/RPO-1000x437-nbv413pszkz7s29g3blop7i6ymcv84f9mtwmvt1xxk-760x380.png 
    * publishedAt : 2017-07-23T17:13:56Z 
    */ 

    private String title; 
    private String url; 
    private String urlToImage; 
    private String publishedAt; 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) {this.title = title;} 

    public String getUrl() { 
     return url; 
    } 

    public void setUrl(String url) { 
     this.url = url; 
    } 

    public String getUrlToImage() { 
     return urlToImage; 
    } 

    public void setUrlToImage(String urlToImage) { 
     this.urlToImage = urlToImage; 
    } 

    public String getPublishedAt() { 
     return publishedAt; 
    } 

    public void setPublishedAt(String publishedAt) { 
     this.publishedAt = publishedAt; 
    } 
} 

從實用工具類的網絡電話樣本JSON響應如下:

{ 
    "status": "ok", 
    "source": "ars-technica", 
    "sortBy": "top", 
    "articles": [{ 
     "author": "Eric Berger", 
     "title": "Elon Musk’s Mars rocket may be about to lose half of its engines", 
     "description": "Downscaling the Mars booster suggests that Musk may be bending toward reality.", 
     "url": "https://arstechnica.com/science/2017/07/elon-musk-drops-an-important-hint-about-his-revised-mars-rocket/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/29937260386_45ba70fb85_h-1440x614-760x380.jpg", 
     "publishedAt": "2017-07-24T13:12:01Z" 
    }, { 
     "author": null, 
     "title": "Hour of Devastation review: The evil elder dragon god-pharaoh has arrived. RIP.", 
     "description": "Plus, a look at the major changes coming to future Magic: the Gathering sets.", 
     "url": "https://arstechnica.com/gaming/2017/07/magic-hour-of-devastation-review/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/401538_CN-copy-760x380.jpg", 
     "publishedAt": "2017-07-24T13:00:52Z" 
    }, { 
     "author": "Annalee Newitz", 
     "title": "Season 2 of Stranger Things looks even creepier and more intense", 
     "description": "The Upside Down is back, and it looks like it's about to eat the world.", 
     "url": "https://arstechnica.com/the-multiverse/2017/07/season-2-of-stranger-things-looks-even-creepier-and-more-intense/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/landscape-1486986380-stranger-things-mike-wheeler-2-760x380.jpg", 
     "publishedAt": "2017-07-23T23:20:39Z" 
    }, { 
     "author": "Annalee Newitz", 
     "title": "First glimpse of Steven Spielberg’s new movie, Ready Player One", 
     "description": "This trailer introduces us to a VR dystopia, and has the greatest soundtrack ever.", 
     "url": "https://arstechnica.com/the-multiverse/2017/07/first-glimpse-of-steven-spielbergs-new-movie-ready-player-one/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/RPO-1000x437-nbv413pszkz7s29g3blop7i6ymcv84f9mtwmvt1xxk-760x380.png", 
     "publishedAt": "2017-07-23T17:13:56Z" 
    }, { 
     "author": null, 
     "title": "New book explores how protesters—and governments—use Internet tactics", 
     "description": "The protest frontiers are changing. An entrenched researcher explains why they work.", 
     "url": "https://arstechnica.com/tech-policy/2017/07/twitter-and-tear-gas-book-explores-new-world-of-digital-protest/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/Screen-Shot-2017-07-22-at-1.17.15-PM-760x380.png", 
     "publishedAt": "2017-07-23T15:00:02Z" 
    }, { 
     "author": "Nathan Mattise", 
     "title": "Maybe The Americans is quietly a technophile love letter to the 1980s", 
     "description": "Joel Fields and Joe Weisberg talk handheld football, spy tech, mail robot, and more.", 
     "url": "https://arstechnica.com/the-multiverse/2017/07/maybe-the-americans-is-quietly-a-technophile-love-letter-to-the-1980s/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/AmericansFootball-600x380.jpg", 
     "publishedAt": "2017-07-23T14:30:15Z" 
    }, { 
     "author": "Sam Machkovech", 
     "title": "Dockless bike sharing lands in Seattle—and leads us down unsavory alleyways", 
     "description": "Now in Seattle: two services, 1,000 bikes, and a shoulder shrug at helmet laws.", 
     "url": "https://arstechnica.com/business/2017/07/dockless-bike-sharing-lands-in-seattle-and-leads-us-down-unsavory-alleyways/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/IMAG3645-760x380.jpg", 
     "publishedAt": "2017-07-23T14:00:32Z" 
    }, { 
     "author": null, 
     "title": "Level up: How video games evolved to solve significant scientific problems", 
     "description": "Science, your chance to use all that time spent gaming for the greater good.", 
     "url": "https://arstechnica.com/gaming/2017/07/level-up-how-video-games-evolved-to-solve-significant-scientific-problems/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/GettyImages-134429675-760x380.jpg", 
     "publishedAt": "2017-07-23T13:25:25Z" 
    }, { 
     "author": "John Timmer", 
     "title": "We’ve screwed up the coasts so badly that an invasive species is a plus", 
     "description": "When native species are gone, an invasive one can provide ecosystem services.", 
     "url": "https://arstechnica.com/science/2017/07/weve-screwed-up-the-coasts-so-badly-that-an-invasive-species-is-a-plus/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/Gracilaria-vermiculophylla-760x380.jpg", 
     "publishedAt": "2017-07-23T12:00:53Z" 
    }, { 
     "author": "Megan Geuss", 
     "title": "German energy company wants to build flow batteries in old natural gas caverns", 
     "description": "Research for a massive redox flow battery is underway.", 
     "url": "https://arstechnica.com/business/2017/07/german-energy-company-wants-to-build-flow-batteries-in-old-natural-gas-caverns/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/20170612-b4p-english-760x380.jpg", 
     "publishedAt": "2017-07-22T15:00:22Z" 
    }] 
} 
+1

你忘記了,響應本身與性質「狀態」,「源」,「排序由」一個大對象和數組「文章「。 – drawinfinity

回答

3

你不能轉換您的JSONObject在一個數組中,你必須有一個jsonArray來做到這一點。只需添加以下行:

JsonObject jsonObject = gson.fromJson(jsonResponse, JsonObject.class); 
String articlesArrayResponse = jsonObject.getAsJsonArray("articles").getAsString(); 

在發生異常之前。顯然你必須改變這一行的論點:

Collection<ArticleResponse> enums = gson.fromJson(articlesArrayResponse, collectionType); 

我希望它可以幫助你!

2

你得到這個錯誤的原因是你的json響應從一個json對象開始,你告訴json解析這個數組的文章響應。

{ 
    "status": "ok", 
    "source": "ars-technica", 
    "sortBy": "top", 
    "articles": [{ 
     "author": "Eric Berger", 
     "title": "Elon Musk’s Mars rocket may be about to lose half of its engines", 
     "description": "Downscaling the Mars booster suggests that Musk may be bending toward reality.", 
     "url": "https://arstechnica.com/science/2017/07/elon-musk-drops-an-important-hint-about-his-revised-mars-rocket/", 
     "urlToImage": "https://cdn.arstechnica.net/wp-content/uploads/2017/07/29937260386_45ba70fb85_h-1440x614-760x380.jpg", 
     "publishedAt": "2017-07-24T13:12:01Z" 
    }, 
    .... 
    }] 
} 

所以爲了做到這一點,你需要首先檢索articles JSON數組,然後把它傳遞給gson.fromJson()方法。你可以做到這一點在做fetchArticleData()方法的一些變化 -

public static List<Article> fetchArticleData(String requestUrl) { 
    String jsonResponse = ""; 
    try { 
     OkHttpClient okHttpClient = new OkHttpClient(); 
     Request request = new Request.Builder() 
       .url(requestUrl) 
       .build(); 
     Response response = okHttpClient.newCall(request).execute(); 
     jsonResponse = response.body().string(); 
     JSONObject jsonObject = new JSONObject(jsonResponse); 
     JSONArray articleArray = jsonObject.getJSONArray("articles"); 
     return extractDataFromJson(articleArray.toString()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
}