【发布时间】:2017-03-07 07:50:16
【问题描述】:
我有一个工作代码,其中我的改造客户可以从 api 检索对象列表(国家)。问题是,如果我曾经检索所有国家/地区,api 使用的参数会返回一个数组,然后当我想查询单个国家/地区时,它会返回一个 OBJECT。结果显示以下异常。
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 4 column 17 path $.RestResponse.result
顺便说一句,我正在使用 Retrofit 2。
我在这个线程中尝试了接受的答案 How to handle parameters that can be an ARRAY or OBJECT in Retrofit on Android?
但它仍然不起作用。这是我的实现。
API
http://services.groupkt.com/country/get/all
http://services.groupkt.com/country/get/iso2code/{alpha2_code}
API接口
public interface ApiInterface {
@GET("country/get/all")
Call<Example> getCountry();
@GET("country/get/iso2code/{alpha2_code}")
Call<Example> searchCountryByIso2Code(@Path("alpha2_code") String alpha2Code);
@GET("country/get/iso3code/{alpha3_code}")
Call<Example> searchCountryByIso3Code(@Path("alpha3_code") String alpha3Code);
@GET("country/search?text={text to search}")
Call<Example> searchCountry(@Path("text to search") String searchText);
}
国家类型适配器
public class CountryTypeAdapter extends TypeAdapter<RestResponse> {
private Gson mGson = new Gson();
@Override
public void write(JsonWriter jsonWriter, RestResponse restResponse) throws IOException {
mGson.toJson(restResponse, RestResponse.class, jsonWriter);
}
@Override
public RestResponse read(JsonReader jsonReader) throws IOException {
RestResponse result;
jsonReader.beginObject();
jsonReader.nextName();
if (jsonReader.peek() == JsonToken.BEGIN_ARRAY) {
result = new RestResponse((Result[]) mGson.fromJson(jsonReader, Result.class));
} else if (jsonReader.peek() == JsonToken.BEGIN_OBJECT) {
result = new RestResponse((Result) mGson.fromJson(jsonReader, Result.class));
} else {
throw new JsonParseException("Unexpected token " + jsonReader.peek());
}
jsonReader.endObject();
return result;
}
}
ApiClient
public class ApiClient {
public static final String BASE_URL = "http://services.groupkt.com/";
private static Retrofit mRetrofit;
public static Retrofit getmRetrofitClient(){
if (mRetrofit == null) {
mRetrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().registerTypeAdapter(CountryTypeAdapter.class, new CountryTypeAdapter()).create()))
.build();
}
return mRetrofit;
}
}
编辑: 休息响应
public class RestResponse {
@SerializedName("messages")
@Expose
private List<String> messages = null;
@SerializedName("result")
@Expose
private List<Result> result = null;
public RestResponse() {
}
public RestResponse(List<String> messages, List<Result> result) {
this.messages = messages;
this.result = result;
}
public RestResponse(Result... result) {
this.result = Arrays.asList(result);
}
public List<String> getMessages() {
return messages;
}
public void setMessages(List<String> messages) {
this.messages = messages;
}
public List<Result> getResult() {
return result;
}
public void setResult(List<Result> result) {
this.result = result;
}
}
【问题讨论】:
-
尝试调用
- > getCountry();并从 APICLIENT 中删除 Gson Tyadapter
-
仍然显示异常..
-
如果 API 响应不同,您不能对所有请求使用“示例”。一个是类似“
- >”的东西,另一个只是一个“Example”对象。
-
我已经添加了 RestResponse 类。从另一个线程我创建了一个接受可变参数的构造函数,这样我就可以将它转换为一个列表,即使它只包含一个对象..
-
您不能重复使用 - private List
result = null - 两个响应。当您获得所有结果时,API 返回一个数组,当您获得一个结果时返回一个“结果”。尝试复制您的 RestResponse 并将其替换为私有 Result 结果