我使用的 API 基本上有 2 个返回值:
单个对象:
{
"data": {Foo}
}
或对象列表:
{
"data": [
{Bar},
{Bar},
...
]
}
所以,我创建了 2 个信封类
class Envelope<T> {
private T data;
public T getData() {
return data;
}
}
class EnvelopeList<T> {
private List<T> data;
public List<T> getData() {
return data;
}
}
和服务接口(interface)
@GET(PATH)
Call<Envelope<Foo>> get();
@GET(PATH_LIST)
Call<EnvelopeList<Bar>> getList();
使用改造 2 配置
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
一切正常...
如果我像这样从服务中删除信封
@GET(PATH)
Call<Foo> get();
@GET(PATH_LIST)
Call<List<Bar>> getList();
第一个仅返回一个仍在工作的对象但返回列表的对象给出错误 java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
因此,我尝试创建一个转换器
public class EnvelopeListConverterFactory extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(
final Type type,
Annotation[] annotations,
Retrofit retrofit) {
Type envelopeType = new ParameterizedType() {
@Override
public Type[] getActualTypeArguments() {
return new Type[]{type};
}
@Override
public Type getRawType() {
return null;
}
@Override
public Type getOwnerType() {
return EnvelopeList.class;
}
};
Converter<ResponseBody, EnvelopeList> delegate =
retrofit.nextResponseBodyConverter(this, envelopeType, annotations);
return new EnvelopeListConverter(delegate);
}
}
public class EnvelopeListConverter<T> implements Converter<ResponseBody, List<T>> {
final Converter<ResponseBody, EnvelopeList<T>> delegate;
EnvelopeListConverter(Converter<ResponseBody, EnvelopeList<T>> delegate) {
this.delegate = delegate;
}
@Override
public List<T> convert(ResponseBody responseBody) throws IOException {
EnvelopeList<T> envelope = delegate.convert(responseBody);
return envelope.getData();
}
}
如果我像这样创建改造版本
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(new EnvelopeListConverterFactory());
我仍然得到和以前一样的错误,但是如果像这样反转转换器顺序
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(new EnvelopeListConverterFactory())
.addConverterFactory(GsonConverterFactory.create());
错误更改为 java.lang.IllegalArgumentException: Unable to create a converter for class Bar for method Service.getList
以及返回单个对象的转换器,也开始出现相同的错误。
我该怎么做才能使服务返回没有信封的对象?
更新
我想我在我的问题上传递了错误的想法。问题不在于请求可以返回单个对象或列表。我只是想通过信封直接获取数据。
我正在尝试这样做 http://f2prateek.com/2017/04/21/unwrapping-data-with-retrofit-2/但它不起作用
最佳答案
我终于找到了如何创建一个正确的转换器类,而不需要在每个请求上都使用信封/包装器。
https://hackernoon.com/retrofit-converter-for-wrapped-responses-8919298a549c
关于java - Retrofit 2 展开信封错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49589463/