问题
I need to send a POST request with duplicate parameter names, like "param=a¶m=b".
Overriding the Request.getParams() does not work since Map cannot have duplicate keys, so only one value would be sent.
I know I can rewrite the Request class to use a Map or Map>, but I was wandering if there is any other way that would not require altering the library.
Thanks in advance.
PS: I have filed the same question on the volley-users group: https://groups.google.com/forum/#!topic/volley-users/tFRclnEbpAk
回答1:
Ficus Kirkpatrick answered my question on the volley-users group (https://groups.google.com/d/msg/volley-users/tFRclnEbpAk/uiC2f9nAIgkJ):
You can override getBody() without having to modify the library.
F
So I created the following helper class:
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HttpParams extends HashMap<String, List<String>> {
private static final long serialVersionUID = 1L;
public HttpParams() {
super();
}
public HttpParams(int capacity) {
super(capacity);
}
public HttpParams(Map<String, List<String>> map) {
super(map);
}
public HttpParams(int capacity, float loadFactor) {
super(capacity, loadFactor);
}
/*
* This is the method to use for adding post parameters
*/
public void add(String key, String value) {
if (containsKey(key)) {
get(key).add(value);
}
else {
ArrayList<String> list = new ArrayList<String>();
list.add(value);
put(key, list);
}
}
/**
* Converts the Map into an application/x-www-form-urlencoded encoded string.
*/
public byte[] encodeParameters(String paramsEncoding) {
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, List<String>> entry : entrySet()) {
String key = URLEncoder.encode(entry.getKey(), paramsEncoding);
for (String value : entry.getValue()) {
encodedParams.append(key);
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(value, paramsEncoding));
encodedParams.append('&');
}
}
return encodedParams.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
}
and then in my class that extends Request I overrided the getBody():
@Override
public byte[] getBody() throws AuthFailureError {
if (mParams != null && mParams.size() > 0) {
return mParams.encodeParameters(getParamsEncoding());
}
return null;
}
回答2:
hey I just answered you in the google group question but I Thought I'd also post it here just in case someone came here first..
It is true that Map does not support duplicate but however that you could do something like this. you won't have to override getBody(), just the getParams which i'm assuming you're already doing.
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();;
params.putAll(AddArrayParams());
return params;
}
public Map<? extends String, ? extends String> AddArrayParams() {
Map<String, String> params = new HashMap<String, String>();
// figure that if its an array and the data is sent as [0],[1] then lets just send it up that way
params.put("param[0]","a");
params.put("param[1]","b");
params.put("param[3]","c");
////etc
return params;
}
Good Luck
来源:https://stackoverflow.com/questions/19999963/google-volley-request-with-duplicate-parameter-names