Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/191.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么改型不能用方括号正确编码查询字符串?_Java_Android_Urlencode_Retrofit - Fatal编程技术网

Java 为什么改型不能用方括号正确编码查询字符串?

Java 为什么改型不能用方括号正确编码查询字符串?,java,android,urlencode,retrofit,Java,Android,Urlencode,Retrofit,我在Android应用程序中对我的网络层进行了改造,但URL编码有问题 我必须这样调用REST API: https://my_hostname.com/some_path?q=some_query&param[0]=value1&param[1]=value2&other_param=abcd 正如您所看到的,查询字符串由一些不同类型的参数组成,因此我决定在带有映射的改装界面中使用@QueryMap注释,其中 q,param[1],param[0],other_par

我在Android应用程序中对我的网络层进行了改造,但URL编码有问题

我必须这样调用REST API:

https://my_hostname.com/some_path?q=some_query&param[0]=value1&param[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;}});