我希望能够反序列化对同一 Java 对象的网络响应,即使响应不成功。目前,当我收到像 403 这样的错误响应时,响应正文为空,我希望使用 response.errorBody() 方法来读取已发回的任何内容,这是可以的。但是我想避免在改造回调中包含大量代码只是为了反序列化 errorBody。相反,我想要一个拦截器,将 errorBody 的内容设置到 body 中。
原因是我有一个响应对象,其中包含错误和非错误响应的字段,并且根据响应的状态,某些字段预计保留为空,例如
错误响应 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;
}
有没有办法在拦截器中做到这一点?
Retrofit 通过将序列化部分委托给转换器来完成序列化部分,您可以使用以下命令将特定的序列化部分添加到构建器builder.addConverterFactory(GsonConverterFactory.create())
并且已经有很多书面的Retrofit Converters,你可以找到其中的大部分here https://github.com/square/retrofit/tree/master/retrofit-converters.
因此,如果您想控制反序列化的过程,您可以编写自定义转换器,如下所示
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 中使用多个转换器,这非常棒,它只需按顺序检查转换器,直到找到合适的转换器即可使用。
资源:编写自定义 Retrofit 转换器 http://blog.davidmedenjak.com/android/2016/07/12/retrofit-converter-unwrapping.html, 使用多个转换器 https://futurestud.io/tutorials/retrofit-2-introduction-to-multiple-converters#2
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)