是否可以以使用泛型类型的方式使用改造?
例如:
public interface RetroInterface<T> {
@GET("content/{id}")
T getById(@Path("id") int id);
}
我已经读过Retrofit使用方法签名来确定运行时的返回类型,在这种情况下,是否可以使用如上所述的通用接口?
答案 0 :(得分:0)
是的,我认为这是可能的,但要小心改造返回一些Call
所以你可以用Call<T>
方法创建一个界面,除了
但您真的需要为服务创建模板吗?因为在你得到注释时你要求服务器一个特定的资源,所以你知道响应的类型
答案 1 :(得分:0)
传递信息的唯一方法是引入一个包装器,以容纳值及其类型(或类型令牌以简化Gson)。
final class GenericBody<T> {
final T body;
final TypeToken<T> typeToken;
GenericBody(final T body, final TypeToken<T> typeToken) {
this.body = body;
this.typeToken = typeToken;
}
}
然后可以将示例服务声明如下:
interface IGenericService {
@POST("/")
Call<Void> post(@Body @SuppressWarnings("rawtypes") GenericBody genericBody);
}
在这里,该Call被声明为不返回任何内容,并且有意将genericBody设为原始类型,以使其通过Retrofit验证。
接下来,是Gson部分。
final class GenericBodyTypeAdapterFactory
implements TypeAdapterFactory {
private static final TypeAdapterFactory genericBodyTypeAdapterFactory = new GenericBodyTypeAdapterFactory();
private GenericBodyTypeAdapterFactory() {
}
static TypeAdapterFactory getGenericBodyTypeAdapterFactory() {
return genericBodyTypeAdapterFactory;
}
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
if ( !GenericBody.class.isAssignableFrom(typeToken.getRawType()) ) {
return null;
}
final TypeAdapter<GenericBody<T>> genericBodyTypeAdapter = new TypeAdapter<GenericBody<T>>() {
@Override
public void write(final JsonWriter out, final GenericBody<T> value)
throws IOException {
final T body = value.body;
final TypeAdapter<T> typeAdapter = gson.getDelegateAdapter(GenericBodyTypeAdapterFactory.this, value.typeToken);
typeAdapter.write(out, body);
}
@Override
public GenericBody<T> read(final JsonReader in) {
throw new UnsupportedOperationException();
}
};
@SuppressWarnings("unchecked")
final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) genericBodyTypeAdapter;
return typeAdapter;
}
}
它是什么:
检查它是否可以处理GenericBody实例; 通过绑定类型标记为解析适当的类型适配器; 将通用主体值写入输出。 没有读取。
使用示例(可轻松转换为代码的完整模拟(staticResponse(applicationJsonMediaType,“ OK”))):
private static final TypeToken<List<String>> stringListTypeToken = new
TypeToken<List<String>>() {
};
private static final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(getGenericBodyTypeAdapterFactory())
.create();
private static final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(staticResponse(applicationJsonMediaType, "OK"))
.build();
private static final Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://whatever")
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
private static final IGenericService genericService =
retrofit.create(IGenericService.class);
public static void main(final String... args)
throws IOException {
final GenericBody<List<String>> body = new GenericBody<>(asList("foo", "bar", "baz"),
stringListTypeToken);
genericService.post(body).execute();
}
这会将[“ foo”,“ bar”,“ baz”]写入输出流,并遵循正确配置的Gson(反)序列化策略。