首页 > 解决方案 > 改造:D/响应:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 $ 处为 BEGIN_OBJECT

问题描述

我想从 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 行第 2 列路径 $ 处为 BEGIN_OBJECT

这是我的 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();

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

标签: androidretrofitrx-javaretrofit2rx-java2

解决方案


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

names: [] // This is a JsonArray

names: {} // This is a JsonObject

推荐阅读