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

时间:2017-09-18 11:11:08

标签: 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);
}

2)当我调用方法getСurrency(someParametr),其中someParametr是字符串,由“date&amp; json”组成(例如,“20170917&amp; 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)我明白了:
网址:https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?date=20170917 %26 json”&amp; 替换为%26 )<登记/> 代码:“404”
4)Inmy界面我添加编码

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

我的结果与第3步相同!

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

4 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:4)

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

使用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的拦截器并用&amp;

替换%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());

答案 2 :(得分:0)

如果您仍然遇到此问题,我有2个解决方案。

第一个解决方案:

// Create a URL object and pass to constructor your url
URL urlObject = new URL(url);
// Create connection
HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection();
// SET 'GET' request
connection.setRequestMethod("GET");
connection.connect();
// Create stream to read output
InputStream inputStream = connection.getInputStream();

// Craete buffer to gain all output
StringBuffer stringBuffer = new StringBuffer();
AND HERE IS THE KEY
YOU CREATE A BUFFERREADER AND SET CP1251 SO URL`S GONNA BE ENCODED
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "cp1251"));
// Read untill end
String line;
while ((line = bufferedReader.readLine()) != null) {
    stringBuffer.append(line);
}
// HERE IS YOUR JSON RESULT
resultJson = stringBuffer.toString();

第二个解决方案:

只需将encoded = true添加到您的@Query批注中

@GET("some_path")
    Call<RequestBody> function(@Query(value = "param", encoded = true) String your_param);

就是这样!所有这些对我来说都很有效。如果您有任何意见或疑问,我会回答。

答案 3 :(得分:-1)

您的Json将拥有关键值数据。尝试传递以下格式。  它会自动在Json密钥之前添加&

getСurrency(@Query("date") String inputDate, @Query("key1") String value1, @Query("key2") String value2);