0

我正在尝试将 New York Times API 与使用 Observable 的 Retrofit 一起使用。但是我在尝试使用数据时遇到了这个错误。

有人可以帮我看看我错在哪里吗?

这是我的 ApiServices 接口:

@GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<TopStoryResult> getTopStories();

@GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<List<NewsItem>> getResults();


Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.nytimes.com/")
        .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()))
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build();

这是我的 ApiStreams 课程

public static Observable<TopStoryResult> streamFetchTopStories(){
    ApiServices mApiServices = ApiServices.retrofit.create(ApiServices.class);
    return mApiServices.getTopStories()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .timeout(10, TimeUnit.SECONDS);
}

public static Observable<List<NewsItem>> streamFetchNews(){
    ApiServices mApiServices = ApiServices.retrofit.create(ApiServices.class);
    return mApiServices.getResults()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .timeout(10, TimeUnit.SECONDS);
}

这就是我在 MainActivity 中尝试做的事情。现在我只想在 TextView 中显示每个标题的列表......

//------------------------
// Update UI
//------------------------
private void updateUIWhenStartingHttpRequest() {
    this.textView.setText("Downloading...");
}


private void updateUIWhenStopingHttpRequest(String response) {
    this.textView.setText(response);
}



//------------------------
// Rx Java
//------------------------
private void executeRequestWithRetrofit(){
    this.updateUIWhenStartingHttpRequest();

    this.disposable = ApiStreams.streamFetchNews()
            .subscribeWith(new DisposableObserver<List<NewsItem>>(){

                @Override
                public void onNext(List<NewsItem> topStories) {
                    Log.e("TAG", "On Next");
                    updateUIWithResult(topStories);
                }

                @Override
                public void onError(Throwable e) {
                    Log.e("ERROR", Log.getStackTraceString(e));
                }

                @Override
                public void onComplete() {
                    Log.e("TAG", "On Complete !");
                }
            });
}



private void updateUIWithResult(List<NewsItem> newsItemList){
    StringBuilder mStringBuilder = new StringBuilder();
    for (NewsItem news : newsItemList){
        Log.e("TAG", "UPDATE UI" + news.getTitle());
        mStringBuilder.append("- " + news.getTitle() + "\n");
    }
    updateUIWhenStopingHttpRequest(mStringBuilder.toString());
}

[编辑] TopStories 和 NewsItem 有我的两个模型

热门故事:

private String status;
private String copyright;
private String section;
private String lastUpdated;
private Integer numResults;
private List<NewsItem> results = null;

public String getStatus() {return status;
}

public void setStatus(String status) {
    this.status = status;
}

public String getCopyright() {
    return copyright;
}

public void setCopyright(String copyright) {
    this.copyright = copyright;
}

public String getSection() {
    return section;
}

public void setSection(String section) {
    this.section = section;
}

public String getLastUpdated() {
    return lastUpdated;
}

public void setLastUpdated(String lastUpdated) {
    this.lastUpdated = lastUpdated;
}

public Integer getNumResults() {
    return numResults;
}

public void setNumResults(Integer numResults) {
    this.numResults = numResults;
}

public List<NewsItem> getResults() {
    return results;
}

public void setResults(List<NewsItem> results) {
    this.results = results;
}

新闻项目:

 private String section;
private String subsection;
private String title;
private String url;
private String byline;
private String updated_date;
private String created_date;
private String published_date;
private String material_type_facet;
private String kicker;


@SerializedName("abstract")
private String abstract_string;

private List<Multimedia> multimedia;


private transient String des_facet;
private transient String org_facet;
private transient String per_facet;
private transient String geo_facet;

public NewsItem() {
}

public NewsItem(String url) {
    this.url = url;
}

public NewsItem(String section, String subsection, String title, String url, String byline, String updated_date, String created_date, String published_date, String material_type_facet, String kicker) {
    this.section = section;
    this.subsection = subsection;
    this.title = title;
    this.url = url;
    this.byline = byline;
    this.updated_date = updated_date;
    this.created_date = created_date;
    this.published_date = published_date;
    this.material_type_facet = material_type_facet;
    this.kicker = kicker;
}

public String getSection() {
    return section;
}

public void setSection(String section) {
    this.section = section;
}

public String getSubsection() {
    return subsection;
}

public void setSubsection(String subsection) {
    this.subsection = subsection;
}

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 getByline() {
    return byline;
}

public void setByline(String byline) {
    this.byline = byline;
}

public String getUpdated_date() {
    return updated_date;
}

public void setUpdated_date(String updated_date) {
    this.updated_date = updated_date;
}

public String getCreated_date() {
    return created_date;
}

public void setCreated_date(String created_date) {
    this.created_date = created_date;
}

public String getPublished_date() {
    return published_date;
}

public void setPublished_date(String published_date) {
    this.published_date = published_date;
}

public String getMaterial_type_facet() {
    return material_type_facet;
}

public void setMaterial_type_facet(String material_type_facet) {
    this.material_type_facet = material_type_facet;
}

public String getKicker() {
    return kicker;
}

public void setKicker(String kicker) {
    this.kicker = kicker;
}


public String getAbstract() {
    return abstract_string;
}

public void setAbstract(String abstract_string) {
    this.abstract_string = abstract_string;
}

public List<Multimedia> getMultimedia() {
    return multimedia;
}

public void setMultimedia(List<Multimedia> multimedia) {
    this.multimedia = multimedia;
}

public String getDes_facet() {
    return des_facet;
}

public void setDes_facet(String des_facet) {
    this.des_facet = des_facet;
}

public String getOrg_facet() {
    return org_facet;
}

public void setOrg_facet(String org_facet) {
    this.org_facet = org_facet;
}

public String getPer_facet() {
    return per_facet;
}

public void setPer_facet(String per_facet) {
    this.per_facet = per_facet;
}

public String getGeo_facet() {
    return geo_facet;
}

public void setGeo_facet(String geo_facet) {
    this.geo_facet = geo_facet;
}

这是 JSON 的样子:

JSON

首先,当我使用 Github 用户 API 尝试这个时,它运行良好。但我不知道我错在哪里......

有人可以帮助我吗?

非常感谢 !

4

2 回答 2

0

In your ApiServices interface you expect that getResults() returns Observable<List<NewsItem>>. Based on JSON you getting back this is not gonna work, because your root JSON element is Object, not an Array.

You have to create new wrapper Class (ResultsWrapper) with "results" field type of List<NewsItem>. Your method in ApiServices interface will then be:

@GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<ResultsWrapper> getResults();

That is what "Expected BEGIN_ARRAY but was BEGIN_OBJECT" says to you.

于 2018-06-19T11:08:05.100 回答
0

预期为 BEGIN_ARRAY 但为 BEGIN_OBJECT 这意味着您正在尝试将 JSON 数组作为 JAVA 中的列表获取,但 api 向您发送了 JSON OBJECT。所以我无法收集足够的信息,但如果我不得不猜测你应该改变这个

@GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<List<NewsItem>> getResults();

@GET("svc/topstories/v2/home.json?api-key=HiddenApiKeyJustForThisMessage")
Observable<NewsItemObject> getResults();

NewsItemObject 是包装 NewsItem 的类

于 2018-06-19T10:51:45.043 回答