改造+可观察 - 预期BEGIN_ARRAY但是BEGIN_OBJECT

时间:2018-06-19 10:39:34

标签: java android retrofit observable

我正在尝试使用Observable使用New York Times API和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有两个模型

TopStories:

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

NewsItem:

 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尝试这个时,它工作正常。但我无法弄清楚我错在哪里......

有人可以帮我吗?

非常感谢!

2 个答案:

答案 0 :(得分:0)

预计BEGIN_ARRAY但是BEGIN_OBJECT 这意味着您正在尝试在JAVA中将JSON数组作为List获取,但是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的类

答案 1 :(得分:0)

ApiServices 界面中,您希望getResults()返回Observable<List<NewsItem>>。基于JSON,你得到回来这是行不通的,因为你的根JSON元素是对象,而不是数组

您必须使用“results”字段类型List<NewsItem>创建新的包装器Class(ResultsWrapper)。您在ApiServices界面中的方法将是:

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

这就是“预期BEGIN_ARRAY但是BEGIN_OBJECT”对你说的。