How to set custom header in Volley Request
Asked Answered
G

13

116

How can custom headers be set for a Volley request? At the moment, there is way to set body content for a POST request. I've a simple GET request, but I need to pass the custom headers alongwith. I don't see how JsonRequest class supports it. Is it possible at all?

Gestate answered 11/6, 2013 at 16:45 Comment(1)
please change the accepted answer, the one currently accepted is incorrect.Astomatous
P
126

It looks like you override public Map<String, String> getHeaders(), defined in Request, to return your desired HTTP headers.

Pomatum answered 11/6, 2013 at 17:43 Comment(2)
@JuanJoséMeleroGómez the link is broken. 404 Not foundRoulette
Here's another example (the snippet at the end of the page): developer.android.com/training/volley/request-custom.html. Class GsonRequest overrides method getHeaders() to return a Map with the header parameters you pass in the constructor.Smollett
A
193

The accepted answer with getParams() is for setting POST body data, but the question in the title asked how to set HTTP headers like User-Agent. As CommonsWare said, you override getHeaders(). Here's some sample code which sets the User-Agent to 'Nintendo Gameboy' and Accept-Language to 'fr':

public void requestWithSomeHttpHeaders() {
    RequestQueue queue = Volley.newRequestQueue(this);
    String url = "http://www.somewebsite.com";
    StringRequest getRequest = new StringRequest(Request.Method.GET, url, 
        new Response.Listener<String>() 
        {
            @Override
            public void onResponse(String response) {
                // response
                Log.d("Response", response);
            }
        }, 
        new Response.ErrorListener() 
        {
            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                Log.d("ERROR","error => "+error.toString());
            }
        }
    ) {     
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError { 
                Map<String, String>  params = new HashMap<String, String>();  
                params.put("User-Agent", "Nintendo Gameboy");  
                params.put("Accept-Language", "fr");

                return params;  
        }
    };
    queue.add(getRequest);

}
Apicella answered 25/10, 2013 at 23:44 Comment(3)
Will this answer work for JSONObjectRequest too? JSONObjectRequest postRequest = new JSONObjectRequest...... because I'm doing this and my getHeaders() is not being called...??? I understand that you're creating an anonymous class and overriding the methods. I'm doing just that only w/ JSONObjectRequest instead of StringRequest and my getHeaders() is not called.Ecumenicalism
Can we add "Cookie" in the getHeaders() method as well? Will it work for post requests as well?Whitewall
Where i will send the rest of POST data?Lazo
P
126

It looks like you override public Map<String, String> getHeaders(), defined in Request, to return your desired HTTP headers.

Pomatum answered 11/6, 2013 at 17:43 Comment(2)
@JuanJoséMeleroGómez the link is broken. 404 Not foundRoulette
Here's another example (the snippet at the end of the page): developer.android.com/training/volley/request-custom.html. Class GsonRequest overrides method getHeaders() to return a Map with the header parameters you pass in the constructor.Smollett
K
31

If what you need is to post data instead of adding the info in the url.

public Request post(String url, String username, String password, 
      Listener listener, ErrorListener errorListener) {
  JSONObject params = new JSONObject();
  params.put("user", username);
  params.put("pass", password);
  Request req = new Request(
     Method.POST,
     url,
     params.toString(),
     listener,
     errorListener
  );

  return req;
}

If what you want to do is edit the headers in the request this is what you want to do:

// could be any class that implements Map
Map<String, String> mHeaders = new ArrayMap<String, String>();
mHeaders.put("user", USER);
mHeaders.put("pass", PASSWORD);
Request req = new Request(url, postBody, listener, errorListener) {
  public Map<String, String> getHeaders() {
    return mHeaders;
  }
}
Kuenlun answered 3/7, 2013 at 10:13 Comment(5)
I downvoted as this isn't what the question asked at all. This is for setting POST content, not for setting custom HTTP headers like User-Agent. Zh. Atanasov and CommonsWare are correct with their getHeaders answers.Apicella
I downvoted this answer because this is not what the user has asked.Soupandfish
This is for adding content params not headers, sorry downvoted too. It really shouldn't be the accepted answerKnownothing
Please can you take a look at my question? It is similar to this but I couldn't get it right stackoverflow.com/a/37948318Naturism
I up voted because this is very helpful for me.Dibb
D
18

You can see this solution. It shows how to get/set cookies, but cookies are just one of the headers in a request/response. You have to override one of the Volley's *Request classes and set the required headers in getHeaders()


Here is the linked source:

public class StringRequest extends com.android.volley.toolbox.StringRequest {

private final Map<String, String> _params;

/**
 * @param method
 * @param url
 * @param params
 *            A {@link HashMap} to post with the request. Null is allowed
 *            and indicates no parameters will be posted along with request.
 * @param listener
 * @param errorListener
 */
public StringRequest(int method, String url, Map<String, String> params, Listener<String> listener,
        ErrorListener errorListener) {
    super(method, url, listener, errorListener);

    _params = params;
}

@Override
protected Map<String, String> getParams() {
    return _params;
}

/* (non-Javadoc)
 * @see com.android.volley.toolbox.StringRequest#parseNetworkResponse(com.android.volley.NetworkResponse)
 */
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
    // since we don't know which of the two underlying network vehicles
    // will Volley use, we have to handle and store session cookies manually
    MyApp.get().checkSessionCookie(response.headers);

    return super.parseNetworkResponse(response);
}

/* (non-Javadoc)
 * @see com.android.volley.Request#getHeaders()
 */
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = super.getHeaders();

    if (headers == null
            || headers.equals(Collections.emptyMap())) {
        headers = new HashMap<String, String>();
    }

    MyApp.get().addSessionCookie(headers);

    return headers;
}

}

And MyApp class:

public class MyApp extends Application {
    private static final String SET_COOKIE_KEY = "Set-Cookie";
    private static final String COOKIE_KEY = "Cookie";
    private static final String SESSION_COOKIE = "sessionid";

    private static MyApp _instance;
    private RequestQueue _requestQueue;
    private SharedPreferences _preferences;

    public static MyApp get() {
        return _instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        _instance = this;
            _preferences = PreferenceManager.getDefaultSharedPreferences(this);
        _requestQueue = Volley.newRequestQueue(this);
    }

    public RequestQueue getRequestQueue() {
        return _requestQueue;
    }


    /**
     * Checks the response headers for session cookie and saves it
     * if it finds it.
     * @param headers Response Headers.
     */
    public final void checkSessionCookie(Map<String, String> headers) {
        if (headers.containsKey(SET_COOKIE_KEY)
                && headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) {
                String cookie = headers.get(SET_COOKIE_KEY);
                if (cookie.length() > 0) {
                    String[] splitCookie = cookie.split(";");
                    String[] splitSessionId = splitCookie[0].split("=");
                    cookie = splitSessionId[1];
                    Editor prefEditor = _preferences.edit();
                    prefEditor.putString(SESSION_COOKIE, cookie);
                    prefEditor.commit();
                }
            }
    }

    /**
     * Adds session cookie to headers if exists.
     * @param headers
     */
    public final void addSessionCookie(Map<String, String> headers) {
        String sessionId = _preferences.getString(SESSION_COOKIE, "");
        if (sessionId.length() > 0) {
            StringBuilder builder = new StringBuilder();
            builder.append(SESSION_COOKIE);
            builder.append("=");
            builder.append(sessionId);
            if (headers.containsKey(COOKIE_KEY)) {
                builder.append("; ");
                builder.append(headers.get(COOKIE_KEY));
            }
            headers.put(COOKIE_KEY, builder.toString());
        }
    }

}
Decasyllable answered 14/6, 2013 at 8:21 Comment(0)
C
18

In Kotlin,

You have to override getHeaders() method like :

val volleyEnrollRequest = object : JsonObjectRequest(GET_POST_PARAM, TARGET_URL, PAYLOAD_BODY_IF_YOU_WISH,
            Response.Listener {
                // Success Part  
            },

            Response.ErrorListener {
                // Failure Part
            }
        ) {
            // Providing Request Headers

            override fun getHeaders(): Map<String, String> {
               // Create HashMap of your Headers as the example provided below

                val headers = HashMap<String, String>()
                headers["Content-Type"] = "application/json"
                headers["app_id"] = APP_ID
                headers["app_key"] = API_KEY

                return headers
            }
        }
Chalybite answered 18/1, 2019 at 10:8 Comment(2)
This is the only resource I could find for overriding headers in Kotlin. Thank you!Genteelism
@MathewSonke I feel you bro. Btw do try Retrofit for networking in Android.Chalybite
O
6

Looking for solution to this problem as well. see something here: http://developer.android.com/training/volley/request.html

is it a good idea to directly use ImageRequest instead of ImageLoader? Seems ImageLoader uses it internally anyway. Does it miss anything important other than ImageLoader's cache support?

ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
...

// Retrieves an image specified by the URL, displays it in the UI.
mRequestQueue = Volley.newRequestQueue(context);;
ImageRequest request = new ImageRequest(url,
  new Response.Listener() {
      @Override
      public void onResponse(Bitmap bitmap) {
          mImageView.setImageBitmap(bitmap);
      }
  }, 0, 0, null,
  new Response.ErrorListener() {
      public void onErrorResponse(VolleyError error) {
          mImageView.setImageResource(R.drawable.image_load_error);
      }
  })   {
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> params = new Map<String, String>();
        params.put("User-Agent", "one");
        params.put("header22", "two");

        return params;
    };
mRequestQueue.add(request);
Orometer answered 8/11, 2014 at 0:8 Comment(2)
It would be much appreciated and more helpful if you could point out why you think the question is wrong or the solution asked has problem, in stead of simply give it a '-1'.Orometer
Map is abstract. Should be HashMapPeddle
C
5

try this

{
    @Override
       public Map<String, String> getHeaders() throws AuthFailureError {
           String bearer = "Bearer ".concat(token);
            Map<String, String> headersSys = super.getHeaders();
            Map<String, String> headers = new HashMap<String, String>();
            headersSys.remove("Authorization");
            headers.put("Authorization", bearer);
            headers.putAll(headersSys);
            return headers;
       }
};
Caduceus answered 18/10, 2016 at 18:7 Comment(0)
P
4

You can make a custom Request class that extends the StringRequest and override the getHeaders() method inside it like this:

public class CustomVolleyRequest extends StringRequest {

    public CustomVolleyRequest(int method, String url,
                           Response.Listener<String> listener,
                           Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = new HashMap<>();
        headers.put("key1","value1");
        headers.put("key2","value2");
        return headers;
    }
}
Permeable answered 30/5, 2017 at 19:56 Comment(0)
R
1
public class CustomJsonObjectRequest  extends JsonObjectRequest
{
    public CustomJsonObjectRequest(int method, String url, JSONObject jsonRequest,Response.Listener listener, Response.ErrorListener errorListener)
    {
        super(method, url, jsonRequest, listener, errorListener);
    }


@Override
public Map getHeaders() throws AuthFailureError {
    Map headers = new HashMap();
    headers.put("AppId", "xyz");

    return headers;
}

}
Reconvert answered 7/3, 2016 at 10:26 Comment(0)
S
1

As addition I'd like to share something I found regarding the Content-Type: On top of

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
.
.
.
return params;
}

I had to add:

@Override
public String getBodyContentType() {
return /*(for exmaple)*/ "application/json";
}

Don't ask me why, I just thought it might help some others that can't get the Content-Type set right.

Stiegler answered 20/12, 2017 at 14:11 Comment(0)
D
0

Here is setting headers from github sample:

StringRequest myReq = new StringRequest(Method.POST,
                       "http://ave.bolyartech.com/params.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);
Dinahdinan answered 23/2, 2014 at 17:39 Comment(0)
P
0

try this

 public void VolleyPostReqWithResponseListenerwithHeaders(String URL,final Map<String, String> params,final Map<String, String> headers,Response.Listener<String> responseListener) {


    String url = URL;

    Log.i("url:", ":" + url);
    StringRequest mStringRequest = new StringRequest(Request.Method.POST,
            url, responseListener, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            // error


            //Log.d("Error.Response", error.getLocalizedMessage());
        }
    }){
        @Override
        protected Map<String, String> getParams() {
            return params;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            return headers;
        }
    };



    mStringRequest.setRetryPolicy(new DefaultRetryPolicy(
            60000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

    mStringRequest.setShouldCache(true);



    //  dialog.show();
    SingletonRequestQueue.getInstance(context).addToRequestQueue(mStringRequest);
}
Polycotyledon answered 4/11, 2015 at 12:24 Comment(3)
@Override public Map<String, String> getHeaders() throws AuthFailureError { return headers; } };Gaw
wheres the header ??Gaw
On signutare, you can set it when you call with Map<String, String> headersPolycotyledon
C
0

That is my code, dont forget = object: if don't put don't works

val queue = Volley.newRequestQueue(this)
        val url = "http://35.237.133.137:8080/lamarrullaWS/rest/lamarrullaAPI"
        // Request a string response from the provided URL.
        val jsonObjectRequest = object: JsonObjectRequest(Request.Method.GET, url, null,
                Response.Listener { response ->
                    txtPrueba.text = "Response: %s".format(response.toString())
                },
                Response.ErrorListener { txtPrueba.text = "That didn't work!" }
        )
        {
            @Throws(AuthFailureError::class)
            override fun getHeaders(): Map<String, String> {
                val headers = HashMap<String, String>()
                headers.put("Content-Type", "application/json")
                return headers
            }
        }
        queue.add(jsonObjectRequest)
Cuticle answered 5/10, 2018 at 5:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.