排球 - POST/GET参数

Zie*_*iem 76 networking android android-volley

我看到关于Volley的Google IO 2013会议,我正在考虑转向凌空.Volley是否支持添加POST/GET参数来请求?如果是,我该怎么办?

Ogn*_*yan 79

对于GET参数,有两种选择:

第一:正如评论中所建议的那样,您可以使用String并将参数占位符替换为其值,例如:

String uri = String.format("http://somesite.com/some_endpoint.php?param1=%1$s&param2=%2$s",
                           num1,
                           num2);

StringRequest myReq = new StringRequest(Method.GET,
                                        uri,
                                        createMyReqSuccessListener(),
                                        createMyReqErrorListener());
queue.add(myReq);
Run Code Online (Sandbox Code Playgroud)

其中num1和num2是包含您的值的String变量.

第二:如果你使用更新的外部HttpClient(例如4.2.x),你可以使用URIBuilder来构建你的Uri.优点是,如果你的uri字符串中已经有参数,那么将它更容易传递给它URIBuilder,然后ub.setQuery(URLEncodedUtils.format(getGetParams(), "UTF-8"));用来添加你的附加参数.这样你就不用费心去检查"?" 已添加到uri或错过了一些,从而消除了潜在错误的来源.

对于POST参数,有时可能比接受的答案更容易,如:

StringRequest myReq = new StringRequest(Method.POST,
                                        "http://somesite.com/some_endpoint.php",
                                        createMyReqSuccessListener(),
                                        createMyReqErrorListener()) {

    protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
        Map<String, String> params = new HashMap<String, String>();
        params.put("param1", num1);
        params.put("param2", num2);
        return params;
    };
};
queue.add(myReq);
Run Code Online (Sandbox Code Playgroud)

例如,只是覆盖getParams()方法.

您可以在Andorid Volley Examples项目中找到一个工作示例(以及许多其他基本的Volley示例).

  • @Yousif如果你问这是一个新问题,你可能会得到更好的答案,但简而言之:POST请求允许你发送不适合GET请求的文件和其他更大的数据.使用GET请求时也存在安全风险,因为URL*可能*记录在服务器上,从而暴露敏感数据. (3认同)
  • 仅图像被缓存。请检查是否有某些代理正在拦截您的请求。如果请求具有完全相同的URL,并且代理很可能只是返回第一个结果。 (2认同)
  • Firefox有一个名为“ HTTP资源测试”的插件,该插件可让您再次向网络服务器发送请求。对于测试这样的案例非常有用。只需输入您的URL(以及POST参数(如果有)),然后查看服务器对多个连续请求的响应。如果再次得到相同的响应结果,则很有可能已缓存。在这种情况下,您可以检查返回的标头,以检查是否有代理标头。关于“不缓存”-是的,它应该可以工作。 (2认同)
  • 我建议您打开一个单独的问题,以便其他人可以加入并提供帮助。请提供信息,说明您正在使用HURL或HttpClient使用哪种堆栈,同时还是要测试的android版本。请在此处添加新问题的链接,以便人们可以关注讨论。 (2认同)

Afz*_*ivE 63

在Request类(扩展Request)中,重写getParams()方法.你会对标题做同样的事情,只需覆盖getHeaders().

如果你在Volley测试中查看TestRequest.java中的PostWithBody类,你会找到一个例子.它就是这样的

public class LoginRequest extends Request<String> {

    // ... other methods go here

    private Map<String, String> mParams;

    public LoginRequest(String param1, String param2, Listener<String> listener, ErrorListener errorListener) {
        super(Method.POST, "http://test.url", errorListener);
        mListener = listener;
        mParams = new HashMap<String, String>();
        mParams.put("paramOne", param1);
        mParams.put("paramTwo", param2);

    }

    @Override
    public Map<String, String> getParams() {
        return mParams;
    }
}
Run Code Online (Sandbox Code Playgroud)

Evan Charlton非常友好地制作了一个快速示例项目,向我们展示如何使用排球. https://github.com/evancharlton/folly/

  • 请注意,`getParams`仅在POST或PUT请求中被调用(默认情况下),***但在GET请求中不是***.见Ogre_BGR的答案 (66认同)
  • 简直不敢相信我直到现在都没注意到 (2认同)
  • @BipinVayalu如果您要连接到Google API,则应该可以使用com.android.volley.AndroidAuthenticator (2认同)

LOG*_*TAG 22

CustomRequest是一种解决Volley的JSONObjectRequest无法发布参数的方法 StringRequest

这里是帮助类,允许添加参数:

    import java.io.UnsupportedEncodingException;
    import java.util.Map;    
    import org.json.JSONException;
    import org.json.JSONObject;    
    import com.android.volley.NetworkResponse;
    import com.android.volley.ParseError;
    import com.android.volley.Request;
    import com.android.volley.Response;
    import com.android.volley.Response.ErrorListener;
    import com.android.volley.Response.Listener;
    import com.android.volley.toolbox.HttpHeaderParser;

    public class CustomRequest extends Request<JSONObject> {

    private Listener<JSONObject> listener;
    private Map<String, String> params;

    public CustomRequest(String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    public CustomRequest(int method, String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return params;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        listener.onResponse(response);
    }

}
Run Code Online (Sandbox Code Playgroud)

感谢Greenchiu

  • 非常感谢,在我得到这个解决方案之前,我正在搜索几个小时,JSONObjectReuqest`getParams()`函数覆盖是不行的,这太奇怪了. (3认同)

And*_*tto 10

此帮助程序类管理GETPOST请求的参数:

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;    

import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;

public class CustomRequest extends Request<JSONObject> {
    private int mMethod;
    private String mUrl;
    private Map<String, String> mParams;
    private Listener<JSONObject> mListener;

    public CustomRequest(int method, String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.mMethod = method;
        this.mUrl = url;
        this.mParams = params;
        this.mListener = reponseListener;
    }

@Override
public String getUrl() {
    if(mMethod == Request.Method.GET) {
        if(mParams != null) {
            StringBuilder stringBuilder = new StringBuilder(mUrl);
            Iterator<Map.Entry<String, String>> iterator = mParams.entrySet().iterator();
            int i = 1;
            while (iterator.hasNext()) {
                Map.Entry<String, String> entry = iterator.next();
                if (i == 1) {
                    stringBuilder.append("?" + entry.getKey() + "=" + entry.getValue());
                } else {
                    stringBuilder.append("&" + entry.getKey() + "=" + entry.getValue());
                }
                iterator.remove(); // avoids a ConcurrentModificationException
                i++;
            }
            mUrl = stringBuilder.toString();
        }
    }
    return mUrl;
}

    @Override
    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return mParams;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        mListener.onResponse(response);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在我们的案例中,迭代器方法销毁了我们传递给函数的原始Map params对象。似乎Volley内部调用了几次GetUrl。我们最终得到了经典的foreach方法,该方法在单独的答案中发布。希望这对谁登陆这里有所帮助。:) (2认同)

Pao*_*llo 6

处理GET参数我迭代了Andrea Motto的解决方案.问题是Volley GetUrl多次调用,他的解决方案使用Iterator破坏了原始的Map对象.随后的Volley内部调用有一个空的params对象.

我还添加了参数编码.

这是内联用法(没有子类).

public void GET(String url, Map<String, String> params, Response.Listener<String> response_listener, Response.ErrorListener error_listener, String API_KEY, String stringRequestTag) {
    final Map<String, String> mParams = params;
    final String mAPI_KEY = API_KEY;
    final String mUrl = url;

    StringRequest stringRequest = new StringRequest(
            Request.Method.GET,
            mUrl,
            response_listener,
            error_listener
    ) {
        @Override
        protected Map<String, String> getParams() {
            return mParams;
        }

        @Override
        public String getUrl() {
            StringBuilder stringBuilder = new StringBuilder(mUrl);
            int i = 1;
            for (Map.Entry<String,String> entry: mParams.entrySet()) {
                String key;
                String value;
                try {
                    key = URLEncoder.encode(entry.getKey(), "UTF-8");
                    value = URLEncoder.encode(entry.getValue(), "UTF-8");
                    if(i == 1) {
                        stringBuilder.append("?" + key + "=" + value);
                    } else {
                        stringBuilder.append("&" + key + "=" + value);
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                i++;

            }
            String url = stringBuilder.toString();

            return url;
        }

        @Override
        public Map<String, String> getHeaders() {
            Map<String, String> headers = new HashMap<>();
            if (!(mAPI_KEY.equals(""))) {
                headers.put("X-API-KEY", mAPI_KEY);
            }
            return headers;
        }
    };

    if (stringRequestTag != null) {
        stringRequest.setTag(stringRequestTag);
    }

    mRequestQueue.add(stringRequest);
}
Run Code Online (Sandbox Code Playgroud)

此函数使用标头传递APIKEY并将TAG设置为在完成之前取消它的有用请求.

希望这可以帮助.