改造Android:java.lang.IllegalStateException:预期BEGIN_ARRAY但在第1行第2列路径处是BEGIN_OBJECT

时间:2015-09-27 13:43:03

标签: android json gson retrofit observable

以前曾问过类似的问题。但它们都不适合我。 我正在尝试返回订阅者正在收听的可观察对象。 每次使用" java.lang.IllegalStateException调用订阅者的onError()方法时:预期BEGIN_ARRAY但在第1行第2列路径为BEGIN_OBJECT $" 此错误

这是我的代码:

public Observable<List<String>> getPlaces() {
    Retrofit retrofit = new Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .baseUrl(Urls.BASE_URL)
        .build();
    RetroFitInterface service = retrofit.create(RetroFitInterface.class);
    return service.getPlaces();
}




public interface RetroFitInterface {

    @Headers({
            "Accept: application/json",
            "Content-Type: application/json"
    })
    @GET(Urls.GET_POPULAR_LOCATIONS_URL)
    Observable<List<String>> getPlaces();
}

这是JSON回应:

{
    "locations": [
        "location1",
        "location2",
        "location3",
        "location4",
        "location5",
        "location6",
        "location7",
    ],
    "success": true
}

这就是我订阅订阅者的方式。

getPlaces().subscribeOn(Schedulers.io())
                .subscribe(new Observer<List<String>>() {
                    @Override
                    public void onCompleted() {
                        Log.d(TAG, "Search result onCompleted()!");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "Search result onError()! " + e.toString());
                    }

                @Override
                public void onNext(final List<String> result) {
                    Log.d(TAG, "This is never called.");
                }
            })

2 个答案:

答案 0 :(得分:3)

目前,您尝试将json反序列化为List<String>类型。但是List<>在json中表示如下:[object1, object2, object3]。另一方面,你的json实际上是一个对象,包含列表。

{
    "locations": [
        "location1",
        "location2",
        "location3",
        "location4",
        "location5",
        "location6",
        "location7",
    ],
    "success": true
}

与上面的json等效的POJO(java类)如下所示:

public class LocationsResponse {

  List<String> locations;
  String success;

}

因此,要回答您的问题,您需要创建LocationsResponse课程并使用 it 作为您的回复类型:

public interface RetroFitInterface {

    @Headers({
            "Accept: application/json",
            "Content-Type: application/json"
    })
    @GET(Urls.GET_POPULAR_LOCATIONS_URL)
    Observable<LocationsResponse> getPlaces();
}

答案 1 :(得分:2)

嗨首先,您需要将json响应转换为POJO。为此,我使用此jsonschema2pojo生成POJO类。

package com.example;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class LocationResponse {

@SerializedName("locations")
@Expose
private List<String> locations = new ArrayList<String>();
@SerializedName("success")
@Expose
private Boolean success;

/**
* 
* @return
* The locations
*/
public List<String> getLocations() {
return locations;
}

/**
* 
* @param locations
* The locations
*/
public void setLocations(List<String> locations) {
this.locations = locations;
}

/**
* 
* @return
* The success
*/
public Boolean getSuccess() {
return success;
}

/**
* 
* @param success
* The success
*/
public void setSuccess(Boolean success) {
this.success = success;
}

}

将此课程放入您所拥有的适当课程中。在下一步中,我更新了您的RetroFitInterface界面,请参阅打击:

public interface RetroFitInterface {

    @Headers({
            "Accept: application/json",
            "Content-Type: application/json"
    })
    @GET(Urls.GET_POPULAR_LOCATIONS_URL)
    Observable<LocationResponse> getPlaces();
}

最后,这就是您订阅订阅者的方式。

getPlaces().subscribeOn(Schedulers.io())
                .subscribe(new Observer<LocationResponse>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                @Override
                public void onNext(final LocationResponse result) {
                    // your result is here
                    if(result.getSuccess()){
                            //result.getLocations();
                    }
                }
            })

如果您需要帮助,请告诉我。