【问题标题】:Retrofit: D/Response: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $改造:D/响应:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 $ 处为 BEGIN_OBJECT
【发布时间】:2019-07-29 23:26:01
【问题描述】:

我想从 URL 的 JSON 响应中获取第一个“城市”对象(或者将它们全部作为数组获取,然后在 RxJava 中使用 .map() 运算符获取第一个城市):

{
    totalResultsCount: 5,
    names: [
        {
            city: stockholm
        },
        {
            city: oslo
        },
        {
            city: london
        },
        {
            city: moscow
        },
        {
            city: mumbai
        }
    ]
}

这是负责获取此内容的代码:

public interface MyApi {

    @GET("searchJSON?")
    Observable<City[]> getPopulation(
        @QueryMap Map<String, String> queries
    );

}

还有这个类

public class MyApiService{

    private final String baseUrl = "myapiurl";
    private MyApi api;
    private final Gson gson;
    private final OkHttpClient okHttpClient;

    public MyApiService(){
        gson = new Gson();
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
        okHttpClient = new OkHttpClient();
        okHttpClient.newBuilder().addInterceptor(httpLoggingInterceptor);
        buildApi();
    }

    private void buildApi(){
        api = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
                .create(MyApi.class);
    }

    public Observable<City> getPopulation(String city) {
        return api
                .getPopulation(city)
                .map(c -> c[0])
                .subscribeOn(Schedulers.io());
    }
}

当我从活动中调用 getPopulation 时,我收到以下消息:

D/响应:应为 BEGIN_ARRAY,但在第 1 行列是 BEGIN_OBJECT 2 路径 $

这是我的 City 类的样子:

public class City {

    @SerializedName("city")
    private String name;

    public City(String name) {
        this.name = name;
    }
}

有什么想法吗?

编辑:

我尝试添加一个自定义反序列化器,例如:

public class MyDeserializer implements JsonDeserializer<City> {

    @Override
    public City deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonElement cities = json.getAsJsonObject().get("names");
        return new Gson().fromJson(cities, City.class);
    }

}

并更改为:

gson = new GsonBuilder()
                .registerTypeAdapter(City.class, new MyDeserializer())
                .create();

但我仍然得到与之前完全相同的响应。

【问题讨论】:

  • 删除我的答案,因为它是 Rx 问题我认为问题是 JSON,尝试使用提到的包装类添加相关信息
  • @cutiko 你的回答也很有帮助。我设法通过更改 GET 方法和我的 getcities 方法并添加一些相关的 RxJava 方法来解决这个问题。感谢您的帮助。
  • 欢迎您,然后发布解决方案

标签: android retrofit rx-java retrofit2 rx-java2


【解决方案1】:

您的自定义反序列化程序使用getAsJsonObject("names"),但名称是您的 json 响应中的 JsonArray。

names: [] // This is a JsonArray

names: {} // This is a JsonObject

【讨论】:

  • 有什么建议可以解析以从我的 get 方法返回城市数组吗?
【解决方案2】:

我设法解决了这个问题。

我将 API 调用更改为:

@GET("searchJSON?")
    Observable<ResponseBody> getPopulation(
        @QueryMap Map<String, String> queries
    );

我将我的api调用方法更改为:

public Observable<City> getPopulation(String city) {
        return api
                .getPopulation(city)
                .map(c -> c.getCities().get(0))
                .subscribeOn(Schedulers.io());

我将我的 Serializeble POJO 更改为:

public class ResponseBody implements Serializable
{

    @SerializedName("totalResultsCount")
    @Expose
    private int totalResultsCount;
    @SerializedName("names")
    @Expose
    private List<City> cities = null;

    public ResponseBody() {
    }

    public ResponseBody(int totalResultsCount, List<City> cities) {
        super();
        this.totalResultsCount = totalResultsCount;
        this.cities = cities;
    }

    public int getTotalResultsCount() {
        return totalResultsCount;
    }

    public void setTotalResultsCount(int totalResultsCount) {
        this.totalResultsCount = totalResultsCount;
    }

    public List<City> getCities() {
        return cities;
    }

    public void setNames(List<City> cities) {
        this.cities = cities;
    }

}

public class City implements Serializable
{
    @SerializedName("name")
    @Expose
    private String name;

    public City() {
    }

    public City(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

我完全删除了自定义反序列化器。

这是我的 POJO 和错误选择 RxJava 操作的组合导致了我的问题。我希望这个答案将来可能对某人有所帮助。

如果有人有更好的解决方案/方法来处理这个问题,我将不胜感激 cmets。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    相关资源
    最近更新 更多