我希望能够将对同一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;
}
有没有办法在拦截器中执行此操作?
答案 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 converter,using 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;
}
};
}