简体   繁体   中英

Json error for Java with Gson and retrofit [Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 70 path $.Data]

I am consuming an API about cryptocurrency news called CryptoCompare. My problem is that I can't detect what my code error is.

The error is as follows -> com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 70 path $.Data

I copy the Json and my two classes to help me find the solution.

Json:

 {
  "Type": 100,
  "Message": "News list successfully returned",
  "Promoted": [

  ],
  "Data": [
    {
      "id": "2940487",
      "guid": "https://cointelegraph.com/news/australian-hacker-pleads-guilty-to-stealing-450-000-in-xrp-last-year",
      "published_on": 1566590880,
      "imageurl": "https://images.cryptocompare.com/news/cointelegraph/dj0O90McM86.png",
      "title": "Australian Hacker Pleads Guilty to Stealing $450,000 in XRP Last Year",
      "url": "https://cointelegraph.com/news/australian-hacker-pleads-guilty-to-stealing-450-000-in-xrp-last-year",
      "source": "cointelegraph",
      "body": "An Australian woman has pleaded guilty to stealing $450,000 in XRP",
      "tags": "Altcoin|Australia|Fraud|Hackers|XRP|Tokens|Police",
      "categories": "XRP|ICO|Altcoin",
      "upvotes": "0",
      "downvotes": "0",
      "lang": "EN",
      "source_info": {
        "name": "CoinTelegraph",
        "lang": "EN",
        "img": "https://images.cryptocompare.com/news/default/cointelegraph.png"
      }
    },

]

Link of Api -> https://min-api.cryptocompare.com/data/v2/news/?lang=EN

Java Class News:

public class News {

@SerializedName("Type")
@Expose
private Integer type;
@SerializedName("Message")
@Expose
private String message;

@SerializedName("Data")
@Expose
private List<Article> articles = null;

@SerializedName("HasWarning")
@Expose
private Boolean hasWarning;

public Integer getType() {
    return type;
}

public void setType(Integer type) {
    this.type = type;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public List<Article> getArticles() {
    return articles;
}

public void setArticles(List<Article> articles) {
    this.articles = articles;
}

public Boolean getHasWarning() {
    return hasWarning;
}

public void setHasWarning(Boolean hasWarning) {
    this.hasWarning = hasWarning;
}

Java Class Article:

public class Article {

@SerializedName("id")
@Expose
private String id;
@SerializedName("guid")
@Expose
private String guid;
@SerializedName("published_on")
@Expose
private Integer publishedOn;
@SerializedName("imageurl")
@Expose
private String imageurl;
@SerializedName("title")
@Expose
private String title;
@SerializedName("url")
@Expose
private String url;
@SerializedName("source")
@Expose
private String source;
@SerializedName("body")
@Expose
private String body;
@SerializedName("tags")
@Expose
private String tags;
@SerializedName("categories")
@Expose
private String categories;
@SerializedName("upvotes")
@Expose
private String upvotes;
@SerializedName("downvotes")
@Expose
private String downvotes;
@SerializedName("lang")
@Expose
private String lang;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getGuid() {
    return guid;
}

public void setGuid(String guid) {
    this.guid = guid;
}

public Integer getPublishedOn() {
    return publishedOn;
}

public void setPublishedOn(Integer publishedOn) {
    this.publishedOn = publishedOn;
}

public String getImageurl() {
    return imageurl;
}

public void setImageurl(String imageurl) {
    this.imageurl = imageurl;
}

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 getSource() {
    return source;
}

public void setSource(String source) {
    this.source = source;
}

public String getBody() {
    return body;
}

public void setBody(String body) {
    this.body = body;
}

public String getTags() {
    return tags;
}

public void setTags(String tags) {
    this.tags = tags;
}

public String getCategories() {
    return categories;
}

public void setCategories(String categories) {
    this.categories = categories;
}

public String getUpvotes() {
    return upvotes;
}

public void setUpvotes(String upvotes) {
    this.upvotes = upvotes;
}

public String getDownvotes() {
    return downvotes;
}

public void setDownvotes(String downvotes) {
    this.downvotes = downvotes;
}

public String getLang() {
    return lang;
}

public void setLang(String lang) {
    this.lang = lang;
}

}

Interface to call Api:

public interface ApiInterface {
    @GET("news")
    Call<News> getNews(
            @Query("lang") String lang,
            @Query("api_key") String apiKey,
            @Query("lTs") int lTs

    );

Retrofit Class Builder

public static Retrofit getApiClient(String BASE_URL){


            retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                    .client(getUnsafeOkHttpClient().build())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();


        return retrofit;
    }

Fragment of Code when i call the api

private void LoadJson(){
        swipeRefreshLayout.setRefreshing(true);
        final ApiInterface apiInterface = ApiClient.getApiClient(ApiUtils.BASE_URL_NEWS).create(ApiInterface.class);

        Call<News> call;

        call = apiInterface.getNews("EN", ApiUtils.API_KEY,0);

        call.enqueue(new Callback<News>() {
            @Override
            public void onResponse(Call<News> call, Response<News> response) {
                if (response.isSuccessful() && response.body() != null){
                    articles.addAll(response.body().getArticles());
                    if (articles.size() - response.body().getArticles().size() == 0){
                        adapterNews.notifyDataSetChanged();
                    } else {
                        adapterNews.notifyItemRangeInserted(articles.size() - response.body().getArticles().size(), response.body().getArticles().size());
                    }


                    swipeRefreshLayout.setRefreshing(false);

                    progressBar.setVisibility(View.GONE);

                } else {
                    Toast.makeText(getContext(), "No result", Toast.LENGTH_SHORT).show();
                    swipeRefreshLayout.setRefreshing(false);

                    progressBar.setVisibility(View.GONE);

                }
            }

            @Override
            public void onFailure(Call<News> call, Throwable t) {
                Log.e(TAG, "ERROR API: " + t.getMessage() + " - " + t.getCause());


            }
        });
    }

Any contribution is very helpful.

Thank you

FIXED THE PROBLEM WAS IN THE CALL

I notice that when you try query on api with wrong value like this

https://min-api.cryptocompare.com/data/v2/news/?lang=en

gives you json instead of array for data so this produce error

For fix and test instead of Locale.getDefault().getLanguage() use just "EN" and check the result

also for more help you can use this logging-interceptor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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