gpt4 book ai didi

retrofit2 - 如何使用Retrofit2,Gson和Rx处理多种可能的响应类型

转载 作者:行者123 更新时间:2023-12-04 08:41:28 27 4
gpt4 key购买 nike

我必须使用糟糕的API,并且总是返回HTTP200。但是有时会有适当的响应:

[{"blah": "blah"}, {"blah": "blah"}]

有时会出现错误:

{"error": "Something went wrong", "code": 123}

我正在将Retrofit2与Gson转换器和Rx适配器一起使用:

final Api api = new Retrofit.Builder()
.baseUrl(URL)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(Api.class);

现在,当我收到错误响应时,会调用 onError处理程序,但有以下异常:
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:117)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$RequestArbiter.request(RxJavaCallAdapterFactory.java:171)
at rx.internal.operators.OperatorSubscribeOn$1$1$1.request(OperatorSubscribeOn.java:80)
at rx.Subscriber.setProducer(Subscriber.java:211)
at rx.internal.operators.OperatorSubscribeOn$1$1.setProducer(OperatorSubscribeOn.java:76)
at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:152)
at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:138)
at rx.Observable.unsafeSubscribe(Observable.java:10144)
at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

我该如何解决?如果可以在 onError处理程序中获得响应,则可以使用适当的错误模型类重新解析它。但似乎我无法得到原始答复。

最佳答案

您可以使用自定义的Gson解串器将两个响应编码(marshal)为单个对象类型。假设您当前的响应类型为List<Map<String, String>>,这是一个大概的想法,您将需要根据实际的返回类型进行调整。我还假设API总是在成功时返回一个数组-

public class MyResponse {
String error;
Integer code;
List<Map<String, String>> response;
}

interface MyApi {
@GET("/")
Observable<MyResponse> myCall();
}

private class MyResponseDeserializer implements JsonDeserializer<MyResponse> {
public MyResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
MyResponse response = new MyResponse();
if (json.isJsonArray()) {
// It is an array, parse the data
Type responseType = new TypeToken<List<Map<String, String>>>(){}.getType();
response.response = context.deserialize(json, responseType);
} else {
// Not an array, parse out the error info
JsonObject object = json.getAsJsonObject();
response.code = object.getAsJsonPrimitive("code").getAsInt();
response.error = object.getAsJsonPrimitive("error").getAsString();
}
return response;
}
}

使用上面的代码创建自定义的 Gson
Gson gson = new GsonBuilder()
.registerTypeAdapter(MyResponse.class, new MyResponseDeserializer())
.create();

在改造生成器中使用它-

.addConverterFactory(GsonConverterFactory.create(gson))

您还应该更新您的界面以返回 Observable<MyResponse>。现在,您将在 onNext中获得成功和错误。您需要检查对象以确定它是否是成功的响应( response != null)。

关于retrofit2 - 如何使用Retrofit2,Gson和Rx处理多种可能的响应类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41693087/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com