改造2:@Query"encoded = false"不起作用

Tom*_*mas 7 java android json retrofit2

0)我正在使用Retrofit 2与Bank API一起工作.
1)我有一些界面:

public interface ApiService {
    @GET("statdirectory/exchange")
    Call<List<MyModel>>  get?urrency(@Query("date") String inputDate);
}
Run Code Online (Sandbox Code Playgroud)

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()+"");      
}
//.....
Run Code Online (Sandbox Code Playgroud)

3)我们发现:
URL: " https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?date=20170917 %26 JSON" (& 被替换%26)
CODE:"404"
4)Inmy接口我添加编码:

get?urrency(@Query(value="date", encoded=false) String inputDate);
Run Code Online (Sandbox Code Playgroud)

我的结果与第3步相同!

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

The*_*eIT 14

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

get?urrency(@Query(value="date", encoded=true) String inputDate);
Run Code Online (Sandbox Code Playgroud)

将导致生成正确的网址。

文档说明了有关encoded参数的以下内容:

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

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


Rag*_*dan 9

如此处所述https://github.com/square/okhttp/issues/2623 by swankjesse

使用HttpUrl构建 url

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

然后将您的方法调用更改为

@GET
Call<List<MyModel>>  get?urrency(@Url String ur);
Run Code Online (Sandbox Code Playgroud)

然后

 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) {

        }

    });
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用 Okhttp 的拦截器并用 & 替换 %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)
 }
}
Run Code Online (Sandbox Code Playgroud)

然后

 OkHttpClient client = new OkHttpClient.Builder();
 client.addInterceptor(new MyInterceptor());
Run Code Online (Sandbox Code Playgroud)