我正在尝试使用此片段https://github.com/square/retrofit/issues/1497用于抛出自定义api错误,与Moshi .

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看到对象的泛型类型而不是数组