2017-07-24 4 views
-1

Avant de supposer que cette question est un doublon basé sur son titre, je dois dire que je n'ai trouvé aucune solution pour mon problème spécifique. Cependant, j'apprécierais que vous suggériez des liens! Cela dit, mon problème est que je continue à obtenir l'exception GSON suivante:Erreur lors de l'analyse des données JSON dans un tableau à l'aide de GSON

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 $ 

Je comprends que je passe en quelque sorte dans un objet JSON, par opposition à un tableau, mais ce que je ne comprends pas comment il est ne travaillant pas en fonction de la classe utilitaire suivante qui a essentiellement des méthodes d'aide pour analyser et extraire des données JSON à partir d'un tableau JSON en utilisant les bibliothèques OkHttpClient et GSON, puis retourne une liste de données extraites à la classe d'appel:

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

Comme vous remarquerez que l'exception est levée dans la ligne de code suivante:

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

est ici la classe ArticleResponse I générées à l'aide GsonFormat:

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

Un échantillon réponse JSON d'un appel réseau dans la classe Utility se présente comme suit:

{ 
    "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

Tu oublies que la réponse elle-même est un grand objet avec les propriétés « état », « source », « tri par », et le tableau " des articles." – drawinfinity

Répondre

3

Vous ne pouvez pas convertir votre JSONObject dans un tableau, vous devez avoir un jsonArray pour le faire. Ajoutez simplement ces lignes:

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

avant que votre exception ne se produise. Évidemment vous devez changer l'argument dans cette ligne pour ceci:

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

J'espère que cela vous aide!

2

La raison pour laquelle vous obtenez cette erreur est que votre réponse json commence par un objet json et que vous demandez à json d'analyser la réponse articles qui est un tableau.

{ 
    "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" 
    }, 
    .... 
    }] 
} 

Ainsi, afin de le faire, vous devez d'abord récupérer le tableau articles JSON et ensuite passer à la méthode gson.fromJson(). Vous pouvez le faire en faisant un changement de méthode 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; 
    } 
}