簡體   English   中英

如何在 Retrofit GET 請求中發送 object 參數?

[英]How to send object parameter in Retrofit GET request?

我有一個像這樣工作的后端服務器

"api/videos?search_object={"cat_id" :2, "channel_id" : 3, etc}

基本上你可以搜索 object 作為輸入,它會根據 object 過濾列表。 現在我想用 Retrofit 使用這個服務,像這樣

@GET("videos")
Call<VideoListResponse> listVideos(@Query("search_object") VideoSearchObject videoSearchObject);

但是上面的代碼不起作用,我可以先將 VideoSearchModel 轉換為 JSON 字符串,然后像這樣將它傳遞給 retrofit

@GET("videos")
Call<VideoListResponse> listVideos(@Query("search_object") String jsonString);

我想知道是否有更好更清晰的方法? 任何建議將不勝感激。

Retrofit 2支持它。 您所要做的就是實現一個自定義轉換器工廠,並重寫stringConverter()方法。

請考慮以下帶有自定義注釋的Retrofit友好界面:

@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"}的編碼表示。

You can try below, it work for me

@GET("api")
Call<Response> method(@Query("") JSONObject param);

Map<String, String> map = new HashMap<>();
map.put("key", "value");
JSONObject json = new JSONObject(map);
 "api/videos?search_object={"cat_id" :2, "channel_id" : 3, etc} 

基本上,您可以將搜索對象作為輸入

不,您不提供對象作為輸入。 您提供了{ }包含的多個參數,以使其看起來像一個對象(JavaScript對象,而不是Java對象)。 實際上它只是一個字符串。

構造的url只是一堆字符。 網址中沒有“對象”這樣的東西。

繼續這樣做@Query("search_object") String jsonString 雖然您可能還想將參數從jsonString重命名為searchString ,因為它就是這樣。 它不是JSON字符串。 JSON字符串將使所有"字符轉義為\\"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM