改造2:@Query“编码=假”不起作用

2022-09-03 08:53:42

0) 我正在使用 Retrofit 2 与 Bank API 配合使用
1)我有一些接口:

public interface ApiService {
    @GET("statdirectory/exchange")
    Call<List<MyModel>>  getСurrency(@Query("date") String inputDate);
}

2)当我调用方法getСurrency(someParametr)时,其中someParametr是字符串,由“date&json”组成(例如,“20170917&json”):

ApiService apiService = RetrofitController.getApi();
apiService.getCurrency("20170917&json").enqueue(new Callback<List<MyModel>>() {

      @Override
      public void onResponse(Call<List<MyModel>> call, Response<List<MyModel>> response) {
          call.request().url();
          Log.e("URL",  call.request().url()+"");
          response.code();
          Log.e("CODE", response.code()+"");      
}
//.....

3)我看到:URL:
https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?date=20170917%26json”&%26取代)
代码:“404”
4)Inmy接口我添加编码

getСurrency(@Query(value="date", encoded=false) String inputDate);

但我的结果与步骤3相同

5)如何检查这个问题?如何在我的字符串上获取没有%26的URL?我阅读了其他具有类似问题的问题,但不能解决我的问题。谢谢!


答案 1

我只是想澄清一下,最初的问题是编码的参数需要为真:true。这表示提供的值已经过编码,因此不需要通过改造重新编码。如改造文档中所述,默认值为 false。结婚encoded=encoded

getСurrency(@Query(value="date", encoded=true) String inputDate);

将导致生成正确的网址。

有关该参数的文档声明如下:encoded

指定参数名称和值是否已进行 URL 编码。

资料来源:https://square.github.io/retrofit/2.x/retrofit/index.html?retrofit2/http/Query.html


答案 2

正如这里所指出的,https://github.com/square/okhttp/issues/2623 由swankjesse

使用 HttpUrl 构建网址

HttpUrl url = HttpUrl.parse("https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?date=20170916&json");

然后将方法调用更改为

@GET
Call<List<MyModel>>  getСurrency(@Url String ur);

然后

 apiService.getCurrency(url.toString())
       .enqueue(new Callback<List<MyModel>>() {

        @Override
        public void onResponse(Call<List<MyModel>> call, retrofit2.Response<List<MyModel>> response) {
            // your response
        }

        @Override
        public void onFailure(Call<List<MyModel>> call, Throwable t) {

        }

    });

另一种方法是使用 Okhttp 的 Interceptor 并将 %26 替换为 &

class MyInterceptor implements Interceptor {
   @Override
   Response intercept(Interceptor.Chain chain) throws IOException {
    Request request = chain.request()
    String stringurl = request.url().toString()
    stringurl = stringurl.replace("%26", "&")

    Request newRequest = new Request.Builder()
        .url(stringurl)
        .build()

    return chain.proceed(newRequest)
 }
}

然后

 OkHttpClient client = new OkHttpClient.Builder();
 client.addInterceptor(new MyInterceptor());