我试图使用此代码段https://github.com/square/retrofit/issues/1497与Moshi一起使用自定义api错误。
API的回报是:
{"error":"message"}
{"failure":"message"}
{"success":"message"}
{...}
[{...},{...},...]
HTTP代码始终为200。
我的改造界面是:
public interface NewsService {
/**
* Get all news
*
* @return
*/
@GET("getActualites.php")
Observable<List<News>> loadNews();
}
所以我创建了泛型类:
public final class ApiResponse<T> {
String failure;
String error;
String success;
T data;
public ApiResponse(String failure, String error, T data) {
this.failure = failure;
this.error = error;
this.data = data;
}
public ApiResponse(T data) {
this.data = data;
}
static class FailureException extends RuntimeException {
public final String error;
public FailureException(String error) {
super("Error message : " + error.getMsg());
this.error = error;
}
}
}
和转换器:
public class ApiErrorHandlerFactory extends Converter.Factory {
public ApiErrorHandlerFactory() {
}
public static Converter.Factory create() {
return new ApiErrorHandlerFactory();
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
Type envelopeType = Types.newParameterizedType(ApiResponse.class, type);
return new ResponseEnvelopeConverter<>(retrofit.nextResponseBodyConverter(this, envelopeType, annotations));
}
private static class ResponseEnvelopeConverter<T> implements Converter<ResponseBody, T> {
private final Converter<ResponseBody, ApiResponse<T>> delegate;
ResponseEnvelopeConverter(Converter<ResponseBody, ApiResponse<T>> delegate) {
this.delegate = delegate;
}
@Override
public T convert(ResponseBody value) throws IOException {
ApiResponse<T> envelope = delegate.convert(value);
if (envelope.failure != null) {
throw new ApiResponse.FailureException(envelope.failure);
}
if (envelope.error != null) {
throw new ApiResponse.FailureException(envelope.error);
}
if (!TextUtils.isEmpty(envelope.success)) {
Timber.d("Success response : %s", envelope.success);
}
return envelope.data;
}
}
}
当API返回错误/失败或成功时,这工作正常,但是当API返回数组时,它无法正常工作。
com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $
at com.squareup.moshi.JsonUtf8Reader.beginObject(JsonUtf8Reader.java:140)
at com.squareup.moshi.ClassJsonAdapter.fromJson(ClassJsonAdapter.java:155)
at com.squareup.moshi.JsonAdapter$2.fromJson(JsonAdapter.java:127)
at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:34)
at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:42)
at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:25)
at fr.mummyz.core.moshi.handler.ApiErrorHandlerFactory$ResponseEnvelopeConverter.convert(ApiErrorHandlerFactory.java:45)
at fr.mummyz.core.moshi.handler.ApiErrorHandlerFactory$ResponseEnvelopeConverter.convert(ApiErrorHandlerFactory.java:36)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:118)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:212)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
我不知道为什么Moshi看到对象的泛型类型而不是数组