88

I saw Google IO 2013 session about Volley and I'm considering switching to volley. Does Volley support adding POST/GET parameters to request? If yes, how can I do it?

4
  • 2
    I didn't see the whole keynote, but I'm pretty sure the GET should be doable just by adding the parameters to the URL (eg. http://example.com?param1=val1&param2=val2)
    – JJJollyjim
    Commented May 19, 2013 at 9:45
  • There seems to be no documentation yet, but you can check the source here android.googlesource.com/platform/frameworks/volley/+/master
    – MM.
    Commented May 19, 2013 at 18:09
  • @JJ56 - Right, but what about POST parameters? I saw source code but didn't find anything related to POST parameters.
    – Ziem
    Commented May 19, 2013 at 19:49
  • 1
    I feel ashamed to say this. But, If you get here asking why your request doesn't have a body on your server, make sure you're using POST/PUT method. Guess I'm just tired. Hope this comment helps anybody or helps me feel better Commented Mar 16, 2018 at 1:37

8 Answers 8

92

For the GET parameters there are two alternatives:

First: As suggested in a comment bellow the question you can just use String and replace the parameters placeholders with their values like:

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);

where num1 and num2 are String variables that contain your values.

Second: If you are using newer external HttpClient (4.2.x for example) you can use URIBuilder to build your Uri. Advantage is that if your uri string already has parameters in it it will be easier to pass it to the URIBuilder and then use ub.setQuery(URLEncodedUtils.format(getGetParams(), "UTF-8")); to add your additional parameters. That way you will not bother to check if "?" is already added to the uri or to miss some & thus eliminating a source for potential errors.

For the POST parameters probably sometimes will be easier than the accepted answer to do it like:

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);

e.g. to just override the getParams() method.

You can find a working example (along with many other basic Volley examples) in the Andorid Volley Examples project.

12
  • I've followed your examples of Volley. So far it's the most helpful Volly code, but I've an issues in JsonObjectRequest. I got the old response in createMyReqSuccessListener until I reinstall it again. Is volley store data in cache? Please suggest a way to do this.
    – SkyWalker
    Commented Jan 16, 2014 at 14:02
  • 2
    Only images are cached. Please check if there is some proxy is intercepting your requests. If the requests has exactly the same URL and it is possible that the proxy is simply returning the first result.
    – Ognyan
    Commented Jan 16, 2014 at 14:23
  • 2
    There is a plugin for Firefox called "HTTP resource test" that allows you to send requests agains web server. It is quite useful for testing cases like this. Just enter your URL (and POST parameters if any) and see what is the response of the server for multiple consecutive requests. If again you get the same response result is most probably cached. In that case you may examine the returned headers to check if there are proxy headers. About the "no-cache" - yes, it should work.
    – Ognyan
    Commented Jan 16, 2014 at 14:34
  • 2
    I suggest that you open separate question so others can join and help.Please provide info what stack are you using HURL or HttpClient, also the android version that are you testing against. Please, put a link to the new question here so people can follow the discussion.
    – Ognyan
    Commented Jan 17, 2014 at 8:30
  • 3
    @Yousif Probably you will get a lot better answers if you ask this as new question, but in short: POST request allows you to send files and other bigger data that will not fit in GET request. Also there is a security risk when using GET request because the URL may get logged on the server thus exposing sensitive data.
    – Ognyan
    Commented Jul 4, 2015 at 10:14
65

In your Request class (that extends Request), override the getParams() method. You would do the same for headers, just override getHeaders().

If you look at PostWithBody class in TestRequest.java in Volley tests, you'll find an example. It goes something like this

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;
    }
}

Evan Charlton was kind enough to make a quick example project to show us how to use volley. https://github.com/evancharlton/folly/

10
  • 76
    Notice that the getParams is only called (by default) in a POST or PUT request, but not in a GET request. See Ogre_BGR's answer Commented Aug 29, 2013 at 10:44
  • 3
    Can't believe I never noticed that until now
    – Afzal N
    Commented Aug 29, 2013 at 16:03
  • @AfzalivE, any idea about how to sign API request with OAuth when using above code? Commented Oct 1, 2013 at 13:17
  • 2
    @BipinVayalu If you are connecting to Google API you should be able to use com.android.volley.AndroidAuthenticator Commented Dec 7, 2013 at 15:52
  • You forgot to instantiate mParams.
    – Moritz
    Commented Aug 15, 2014 at 10:38
23

CustomRequest is a way to solve the Volley's JSONObjectRequest can't post parameters like the StringRequest

here is the helper class which allow to add params:

    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);
    }

}

thanks to Greenchiu

3
  • 3
    Thanks alot, I was searching for hours before I get this solution, It's so weird that JSONObjectReuqest getParams() function overriding is not working. Commented Jul 3, 2014 at 17:47
  • @MohammadWalid FYI read this stackoverflow.com/questions/16902716/… and try to use retrofit! both volley and retrofit can be used with okhttp!
    – LOG_TAG
    Commented Jul 4, 2014 at 4:15
  • I tried this solution, but didn't work for me. getParams() is not called.
    – Matt
    Commented Apr 17, 2019 at 2:30
10

This helper class manages parameters for GET and POST requests:

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);
    }
}
4
  • This solves adding parameters to the GET method, Thank You!
    – pkarc
    Commented Jan 13, 2016 at 16:45
  • 2
    In our case the iterator approach destroyed the original Map params object we passed to the function. Seems Volley internally calls GetUrl several times. We ended up with a classic foreach approach as posted in a separate answer. Hope this helps who lands here. :) Commented Apr 19, 2016 at 16:04
  • How to call this helper class for get request with 3 parameters
    – kgandroid
    Commented Apr 26, 2018 at 19:13
  • @kgandroid, create a Map<String, String> with your keys and values. Example: Map<String, String> params = new HashMap<String, String>(); params.put("param1", "value1"); params.put("param2", "value2"); params.put("param3", "value3"); Commented Apr 26, 2018 at 23:53
6

Dealing with GET parameters I iterated on Andrea Motto' solution. The problem was that Volley called GetUrl several times and his solution, using an Iterator, destroyed original Map object. The subsequent Volley internal calls had an empty params object.

I added also the encode of parameters.

This is an inline usage (no subclass).

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);
}

This function uses headers to pass an APIKEY and sets a TAG to the request useful to cancel it before its completion.

Hope this helps.

3

This may help you...

private void loggedInToMainPage(final String emailName, final String passwordName) {

    String tag_string_req = "req_login";
    StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://localhost/index", new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            Log.d(TAG, "Login Response: " + response.toString());
            try {
                JSONObject jsonObject = new JSONObject(response);
                Boolean error = jsonObject.getBoolean("error");
                if (!error) {

                    String uid = jsonObject.getString("uid");
                    JSONObject user = jsonObject.getJSONObject("user");
                    String email = user.getString("email");
                    String password = user.getString("password");


                    session.setLogin(true);
                    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(intent);
                    finish();
                    Toast.makeText(getApplicationContext(), "its ok", Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {
            System.out.println("volley Error .................");
        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("tag", "login");
            params.put("email", emailName);
            params.put("password", passwordName);
            return params;
        }
    };


    MyApplication.getInstance().addToRequestQueue(stringRequest,tag_string_req);
}
2

For Future Readers

I love to work with Volley. To save development time i tried to write small handy library Gloxey Netwok Manager to setup Volley with my project. It includes JSON parser and different other methods that helps to check network availability.

Use ConnectionManager.class in which different methods for Volley String and Volley JSON request are available. You can make requests of GET, PUT, POST, DELETE with or without header. You can read full documentation here.

Just put this line in your gradle file.

  dependencies { 

       compile 'io.gloxey.gnm:network-manager:1.0.1'
   }

Volley StringRequest

Method GET (without header)

    ConnectionManager.volleyStringRequest(context, isDialog, progressDialogView, requestURL, volleyResponseInterface);

How to use?

     Configuration                Description

     Context                      Context 
     isDialog                     If true dialog will appear, otherwise not.
     progressView                 For custom progress view supply your progress view id and make isDialog true. otherwise pass null. 
     requestURL                   Pass your API URL.  
     volleyResponseInterface      Callback for response.  

Example

    ConnectionManager.volleyStringRequest(this, false, null, "url", new VolleyResponse() {
    @Override
    public void onResponse(String _response) {

        /**
         * Handle Response
         */
    }

    @Override
     public void onErrorResponse(VolleyError error) {

        /**
         * handle Volley Error
         */
    }

    @Override
    public void isNetwork(boolean connected) {

        /**
         * True if internet is connected otherwise false
         */
    }
});

Volley StringRequest

Method POST/PUT/DELETE (without header)

    ConnectionManager.volleyStringRequest(context, isDialog, progressDialogView, requestURL, requestMethod, params, volleyResponseInterface);

Example

Use Method : Request.Method.POST
             Request.Method.PUT
             Request.Method.DELETE

Your params : 

HashMap<String, String> params = new HashMap<>();
params.put("param 1", "value");
params.put("param 2", "value");

ConnectionManager.volleyStringRequest(this, true, null, "url", Request.Method.POST, params, new VolleyResponse() {
    @Override
    public void onResponse(String _response) {

        /**
         * Handle Response
         */
    }

    @Override
    public void onErrorResponse(VolleyError error) {

        /**
         * handle Volley Error
         */
    }

    @Override
    public void isNetwork(boolean connected) {

        /**
         * True if internet is connected otherwise false
         */
    }
});

Bonus

Gloxey JSON Parser

Feel free to use gloxey json parser to parse your api response.

  YourModel yourModel = GloxeyJsonParser.getInstance().parse(stringResponse, YourModel.class);

Example

ConnectionManager.volleyStringRequest(this, false, null, "url", new VolleyResponse() {
    @Override
    public void onResponse(String _response) {

        /**
         * Handle Response
         */

         try {

          YourModel yourModel = GloxeyJsonParser.getInstance().parse(_response, YourModel.class);

            } catch (Exception e) {
                e.printStackTrace();
            }

    }

    @Override
     public void onErrorResponse(VolleyError error) {

        /**
         * handle Volley Error
         */
         if (error instanceof TimeoutError || error instanceof NoConnectionError) {

                showSnackBar(parentLayout, getString(R.string.internet_not_found), getString(R.string.retry), new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                     //handle retry button

                    }
                });

            } else if (error instanceof AuthFailureError) {
            } else if (error instanceof ServerError) {
            } else if (error instanceof NetworkError) {
            } else if (error instanceof ParseError) {
            }

    }

    @Override
    public void isNetwork(boolean connected) {

        /**
         * True if internet is connected otherwise false
         */
          if (!connected) {
                showSnackBar(parentLayout, getString(R.string.internet_not_found), getString(R.string.retry), new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        //Handle retry button
                    }
                });
    }
});


     public void showSnackBar(View view, String message) {
            Snackbar.make(view, message, Snackbar.LENGTH_LONG).show();
     }

     public void showSnackBar(View view, String message, String actionText, View.OnClickListener onClickListener) {
            Snackbar.make(view, message, Snackbar.LENGTH_LONG).setAction(actionText, onClickListener).show();
     }
2
0

To provide POST parameter send your parameter as JSONObject in to the JsonObjectRequest constructor. 3rd parameter accepts a JSONObject that is used in Request body.

JSONObject paramJson = new JSONObject();

paramJson.put("key1", "value1");
paramJson.put("key2", "value2");


JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,url,paramJson,
    new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {

        }
    },
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });
requestQueue.add(jsonObjectRequest);

Not the answer you're looking for? Browse other questions tagged or ask your own question.