Retrofit:在@GET命令中使用多个查询参数?

71

我在我的Android应用程序中使用Retrofit和Robospice进行API调用。所有@POST方法都很好用,没有URL参数的@GET命令也可以正常工作,但是在结尾附加参数的@GET调用无法工作!

例如,如果我的API路径是“my/api/call/”,并且我想在URL中添加2个参数“param1”和“param2”,则get调用将如下所示:

http://www.example.com/my/api/call?param1=value1&param2=value2

因此,我已经设置了我的@GET接口如下:

@GET("/my/api/call?param1={p1}&param2={p2}")
Response getMyThing(@Path("p1")
String param1, @Path("p2")
String param2);

但是我收到了一个错误,指出:"在执行请求网络时发生异常: getMyThing方法上的URL查询字符串"/my/api/call?param1={p1}&param2={p2}"可能没有替换区块。"

我做错了什么?

7个回答

142

您应该使用以下语法:

@GET("/my/API/call")
Response getMyThing(
    @Query("param1") String param1,
    @Query("param2") String param2);

在URL中指定查询参数仅适用于您已经知道键和值都是固定的情况。

2
我现在遇到了以下错误:11-14 10:29:48.626: E//RequestRunner.java:134(31776): 10:29:48.630 Thread-11782 在请求网络执行期间发生异常:null我肯定在我的spicemanager中设置了接口,不确定什么可能为空... - AndroidNoob
2
抱歉,我不确定。我从未使用过RoboSpice。我只是为了Retrofit在这里 :) - Jake Wharton
嗨,杰克,如果你需要自己构造查询参数,那么这将是完美的方案,但如果它们已经提前给了你呢?想象一下一个模板响应,告诉你从哪里获取信息,并为你设置了这些参数。因此,/my/api/call?param1={p1}&param2={p2} 不是由你手动创建的,而是在另一个调用的响应中向你提供的。 - Javier Tarazaga
1
@Javier Tarazaga 抱歉回复晚了,但在Retrofit 1和2中,您可以使用QueryMap - 可以参考这个例子 - AndroidNoob

23

如果您有大量的GET参数,将它们传递到您的URL中的另一种方法是使用HashMap。

class YourActivity extends Activity {

    private static final String BASEPATH = "http://www.example.com";

    private interface API {
        @GET("/thing")
        void getMyThing(@QueryMap Map<String, String>, new Callback<String> callback);
    }

    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.your_layout);

       RestAdapter rest = new RestAdapter.Builder().setEndpoint(BASEPATH).build();
       API service      = rest.create(API.class);

       Map<String, String> params = new HashMap<String, String>();
       params.put("foo", "bar");
       params.put("baz", "qux");
       // ... as much as you need.

       service.getMyThing(params, new Callback<String>() {
           // ... do some stuff here.
       });
    }
}

所调用的URL将为http://www.example.com/thing/?foo=bar&baz=qux


这正是我在寻找的,我们可以使用它发送多个查询参数。 - Hamza Khan

16
您可以创建一个参数的映射表,然后像下面这样发送它:
Map<String, String> paramsMap = new HashMap<String, String>();
paramsMap.put("p1", param1);
paramsMap.put("p2", param2);

// Inside call
@GET("/my/api/call")
Response getMyThing(@QueryMap Map<String, String> paramsMap);

1
这是一个更好的解决方案,我不知道为什么它没有被选为最佳答案。 - smrf

6
不要将查询参数写在GET-URL中,可以像这样处理:
@GET("/my/api/call")
Response getMyThing(@Query("param1") String param1,
                    @Query("param2") String param2);

3

使用Java

@GET("/my/api/call")
Response getMyThing(@Query("p1")
String param1, @Query("p2")
String param2);

使用Kotlin协程
 @GET("/my/api/call")
 suspend fun getSearchProduct(@Query("p1") p1: String , @Query("p2") p2: String )

0

使用 Composable 的 Retrofit

@GET("api_link_put_here")
fun getapi_link_put_here(@Query("firstParam") firstParam: String,
                         @Query("second_param") second_param: String): 
 Call<ResponseBody>

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接