Java 为什么改型不能用方括号正确编码查询字符串?
我在Android应用程序中对我的网络层进行了改造,但URL编码有问题 我必须这样调用REST API:Java 为什么改型不能用方括号正确编码查询字符串?,java,android,urlencode,retrofit,Java,Android,Urlencode,Retrofit,我在Android应用程序中对我的网络层进行了改造,但URL编码有问题 我必须这样调用REST API: https://my_hostname.com/some_path?q=some_query¶m[0]=value1¶m[1]=value2&other_param=abcd 正如您所看到的,查询字符串由一些不同类型的参数组成,因此我决定在带有映射的改装界面中使用@QueryMap注释,其中 q,param[1],param[0],other_par
https://my_hostname.com/some_path?q=some_query¶m[0]=value1¶m[1]=value2&other_param=abcd
正如您所看到的,查询字符串由一些不同类型的参数组成,因此我决定在带有映射的改装界面中使用@QueryMap
注释,其中
q,param[1],param[0],other_param
是映射的字符串键
我期待什么?
我希望URL中的方括号对'['
用%5B
编码,对'['
用%5D
编码,但这并没有发生
为什么会发生这种情况?方括号应该用百分比编码。这是一个错误还是我做错了什么?我也尝试了@EncodedQueryMap
注释,没有任何区别。查询名称从来都不是URL编码的
@QueryMap
的文档说明:
值是URL编码的
对于@EncodedQueryMap
:
值不是URL编码的
不过,我只是想稍微改变一下这种行为。我正在通过使用@Query(value=“…”,encodeName=true)
或@QueryMap(encodeNames=true)
尝试简单的方法来添加对密钥编码的支持
@得到
和parameters@Query此外,如果值包含带有JSONObject的JSONArray,则改型不会对括号[]{}进行编码
地图包含以下元素:
key = filter,
value = [{"field":"some_field","value":"some_value","operator":"="}]
和@QueryMap send
http://my_server/api?filter=[{%22field%22:%22some_field%22,%22value%22:%22some_value%22,%22operator%22:%22%3D%22}]
那里使用了QueryMap,因为GET请求中的number参数和filter选项中的objects。我只需要处理@QueryMap
编码一切,而不是{}[]
。大多数情况下,我并不介意,因为我很少在查询中发送json,并且希望在应用程序堆栈中尽可能降低编码,但最近我不得不添加一个端点,就像Ivan所描述的那样。我的解决方案是添加一个拦截器,可以做到这一点:
Request originalRequest = chain.request();
HttpUrl url = originalRequest.url();
String urlFilePath = url.encodedPath();
if(url.encodedQuery() != null) {
// Because Retrofit doesn't think "{}[]" should be encoded
// but our API does
String correctlyEncodedQuery = correctlyEncodeQuery(url);
urlFilePath += "?" + correctlyEncodedQuery;
}
URL correctUrl = new URL(url.scheme(), url.host(), url.port(),
urlFilePath);
Request newRequest = originalRequest.newBuilder()
.url(correctUrl)
private String correctlyEncodeQuery(HttpUrl url) throws UnsupportedEncodingException {
String retVal = "";
for(String queryKey : url.queryParameterNames()){
if(retVal.length() > 0){
retVal += "&";
}
String queryValue = url.queryParameter(queryKey);
retVal += queryKey + "=" + URLEncoder.encode(queryValue, "utf-8");
}
return retVal;
}
看起来您的rest api应该期望params
是一个值数组。我认为您的rest服务器不应该使用[]
在变量名中,但与其他地方一样,将其用作列表指示符,在这种情况下,不需要对括号进行编码。如果不对括号进行编码,服务器API将无法正常工作。我需要对括号进行编码,但我想知道如何进行改装,而不是手动。这解决了我的问题,我不想t对查询值进行编码,因此我改为设置@query(value=“…”,encodeValue=false)post请求如何?干净且简单。如果有人想知道这是添加在OkHttpClient.Builder()
上的,例如new OkHttpClient.Builder()。addNetworkInterceptor(new Interceptor(){@Override public Response intercept(Chain Chain)抛出IOException{return null;}});