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 的网址?我读了类似问题的其他问题,但没有解决我的问题。谢谢!
答案 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;
替换%26class 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);