如何在Retrofit GET请求中发送对象参数?
问题描述:
我有一个是这样的如何在Retrofit GET请求中发送对象参数?
"api/videos?search_object={"cat_id" :2, "channel_id" : 3, etc}
Basily后端服务器,你可以给作为输入搜索对象,它会筛选对象的名单基地。现在我想的东西与改造要使用这项服务这样
@GET("videos")
Call<VideoListResponse> listVideos(@Query("search_object") VideoSearchObject videoSearchObject);
但上面的代码不工作,我可以先转换VideoSearchModel给它传递加装这样
@GET("videos")
Call<VideoListResponse> listVideos(@Query("search_object") String jsonString);
JSON字符串
我想知道是否有更好的更清晰的方法?任何建议将不胜感激。
答
"api/videos?search_object={"cat_id" :2, "channel_id" : 3, etc}
基本上可以给出搜索对象作为输入
不,你不给一个对象作为输入。您提供了包含在{ }
中的多个参数,以便它看起来像对象(不是Java对象的JavaScript对象)。实际上它只是一个字符串。
构造的url只是一串字符。在url中不存在“对象”这样的东西。
继续做下去就像@Query("search_object") String jsonString
。虽然您可能也想要将参数jsonString
重命名为searchString
,因为这就是它的原因。它不是JSON字符串。一个JSON字符串可以让所有"
字符像\"
一样被转义。
答
Retrofit 2支持它。所有你需要做的是用stringConverter()
方法重写实现一个自定义转换器工厂。
考虑以下改造友好接口与自定义注解:
@Target(PARAMETER)
@Retention(RUNTIME)
@interface ToJson {
}
interface IService {
@GET("api/videos")
Call<Void> get(
@ToJson @Query("X") Map<String, Object> request
);
}
注释用于表示必须被转换成字符串的参数。
模拟OkHttpClient
总是与 “HTTP 200 OK” 响应,并转储请求的URL:
private static final OkHttpClient mockHttpClient = new OkHttpClient.Builder()
.addInterceptor(chain -> {
System.out.println(chain.request().url());
return new Response.Builder()
.request(chain.request())
.protocol(HTTP_1_0)
.code(HTTP_OK)
.body(ResponseBody.create(MediaType.parse("application/json"), "OK"))
.build();
})
.build();
private static final Gson gson = new Gson();
private static final Retrofit retrofit = new Retrofit.Builder()
.client(mockHttpClient)
.baseUrl("http://whatever")
.addConverterFactory(new Converter.Factory() {
@Override
public Converter<?, String> stringConverter(final Type type, final Annotation[] annotations, final Retrofit retrofit) {
if (!hasToJson(annotations)) {
return super.stringConverter(type, annotations, retrofit);
}
return value -> gson.toJson(value, type);
}
private boolean hasToJson(final Annotation[] annotations) {
for (final Annotation annotation : annotations) {
if (annotation instanceof ToJson) {
return true;
}
}
return false;
}
})
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
为了测试它,你可以简单地调用服务接口方法:
final IService service = retrofit.create(IService.class);
service.get(ImmutableMap.of("k1", "v1", "k2", "v2")).execute();
结果:
HTTP://任何/ API /视频X = {%22k1%22:%22v1%22%部22k2附近%22:%22v2%22}
凡X
参数参数是一个编码表示{"k1":"v1","k2":"v2"}
。
如果你想在查询中发送json字符串,恐怕这是唯一的方法。 –