Retrofit2即使响应不是200

时间:2017-07-04 13:12:38

标签: android retrofit2

我希望能够将对同一Java对象的网络响应反序列化,即使响应不成功。目前,当我得到像403这样的错误响应时,响应体为null,我希望使用response.errorBody()方法读取已经发回的内容,这没关系。但是我想避免在改装回调中有很多代码只是为了反序列化errorBody。相反,我希望有一个拦截器将errorBody的内容设置为body。

原因是我有一个响应对象,其中包含错误和非错误响应的字段,并且根据响应的状态,某些字段应该保留为null,例如

错误响应JSON

{
"locked":true,
"remaining_attempts": 2
}

成功回应JSON

{
"name":"kev"
"token":"abcdefghijklmnopq"
}

我创建了一个捕获两种场景的Java对象:

class LoginResponse{
    @Expose
    private String name;
    @Expose
    private String token;
    @Expose
    private Boolean locked;
    @Expose
    private Integer remaining_attempts;
}

有没有办法在拦截器中执行此操作?

2 个答案:

答案 0 :(得分:1)

Retrofit通过将其委托给Converter进行序列化部分,您可以使用builder.addConverterFactory(GsonConverterFactory.create())向构建器添加特定的部分。 并且已经有很多书面的改装转换器,您可以找到其中大多数here

所以如果你想控制这个反序列化过程,可以编写自定义转换器,就像这样

public class UnwrapConverterFactory extends Converter.Factory {

    private GsonConverterFactory factory;

    public UnwrapConverterFactory(GsonConverterFactory factory) {
        this.factory = factory;
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(final Type type,
            Annotation[] annotations, Retrofit retrofit) {
        // e.g. WrappedResponse<Person>
        Type wrappedType = new ParameterizedType() {
            @Override
            public Type[] getActualTypeArguments() {
                // -> WrappedResponse<type>
                return new Type[] {type};
            }

            @Override
            public Type getOwnerType() {
                return null;
            }

            @Override
            public Type getRawType() {
                return WrappedResponse.class;
            }
        };
        Converter<ResponseBody, ?> gsonConverter = factory
                .responseBodyConverter(wrappedType, annotations, retrofit);
        return new WrappedResponseBodyConverter(gsonConverter);
    }
}

然后再次使用addConverterFactory()告诉Retrofit新转换器。 我应该提一下,你可以在Retrofit中使用多个转换器,它很棒,只需按顺序检查转换器,直到找到合适的转换器。

资源:writing custom Retrofit converterusing multiple converters

答案 1 :(得分:0)

您可以直接回复以下内容......

    LoginResponse errorResponse = gson.fromJson(response.errorBody().string(), LoginResponse.class);

...或使用拦截器

addInterceptor(getMyErrorResponseInterceptor())


protected Interceptor getMyErrorResponseInterceptor() {
    return new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Response response = chain.proceed(request);
            if (response.code() >= 400) {

                // handle error
            }

            return response;
        }
    };
}