Comment définir un en-tête personnalisé dans Volley Request

104

Comment définir des en-têtes personnalisés pour une requête Volley? Pour le moment, il existe un moyen de définir le contenu du corps pour une requête POST. J'ai une simple requête GET, mais je dois transmettre les en-têtes personnalisés avec. Je ne vois pas comment la classe JsonRequest le prend en charge. Est-ce possible du tout?

Bianca
la source
veuillez modifier la réponse acceptée, celle actuellement acceptée est incorrecte.
Esteban

Réponses:

119

Il semble que vous remplaciez public Map<String, String> getHeaders(), défini dansRequest , pour renvoyer les en-têtes HTTP souhaités.

CommonsWare
la source
4
@ JuanJoséMeleroGómez le lien est rompu. 404 Not found
Milon
Voici un autre exemple (l'extrait à la fin de la page): developer.android.com/training/volley/request-custom.html . La classe GsonRequestremplace la méthode getHeaders()pour renvoyer une carte avec les paramètres d'en-tête que vous passez au constructeur.
Juan José Melero Gómez
157

La réponse acceptée avec getParams () est de définir les données du corps POST, mais la question dans le titre demandait comment définir les en-têtes HTTP comme User-Agent. Comme CommonsWare l'a dit, vous remplacez getHeaders (). Voici un exemple de code qui définit User-Agent sur «Nintendo Gameboy» et Accept-Language sur «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);

}
Georgiecasey
la source
Cette réponse fonctionnera-t-elle également pour JSONObjectRequest? JSONObjectRequest postRequest = new JSONObjectRequest ...... parce que je fais cela et que mon getHeaders () n'est pas appelé ... ??? Je comprends que vous créez une classe anonyme et remplacez les méthodes. Je fais juste cela uniquement avec JSONObjectRequest au lieu de StringRequest et mon getHeaders () n'est pas appelé.
JDOaktown
Pouvons-nous également ajouter "Cookie" dans la méthode getHeaders ()? Cela fonctionnera-t-il également pour les demandes de publication?
Arnab Banerjee
Où vais-je envoyer le reste des données POST?
Fernando Torres
30

Si vous avez besoin de publier des données au lieu d'ajouter les informations dans l'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;
}

Si vous souhaitez modifier les en-têtes de la requête, voici ce que vous souhaitez faire:

// 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;
  }
}
thepoosh
la source
44
J'ai décliné car ce n'est pas du tout ce que la question posait. Ceci est pour définir le contenu POST, pas pour définir des en-têtes HTTP personnalisés comme User-Agent. Zh. Atanasov et CommonsWare ont raison dans leurs getHeadersréponses.
georgiecasey
4
J'ai décliné cette réponse car ce n'est pas ce que l'utilisateur a demandé.
Dharmendra Pratap Singh
1
Ceci est pour ajouter des paramètres de contenu et non des en-têtes, désolé aussi. Cela ne devrait vraiment pas être la réponse acceptée
Juan Cortés
1
Pouvez-vous jeter un oeil à ma question? C'est similaire à ça mais je n'ai pas pu le faire correctement stackoverflow.com/a/37948318
X09
18

Vous pouvez voir cette solution. Il montre comment obtenir / définir des cookies, mais les cookies ne sont que l'un des en-têtes d'une demande / réponse. Vous devez remplacer l'une des classes * Request de Volley et définir les en-têtes requis dansgetHeaders()


Voici la source liée:

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

}

Et classe MyApp:

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

}
Zh. Atanasov
la source
7

À Kotlin,

Vous devez remplacer la méthode getHeaders () comme:

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
            }
        }
devDeejay
la source
1
C'est la seule ressource que j'ai pu trouver pour remplacer les en-têtes dans Kotlin. Je vous remercie!
Mathew Sonke le
@MathewSonke Je te sens frère. Btw, essayez Retrofit pour la mise en réseau sous Android.
devDeejay
6

Vous cherchez également une solution à ce problème. voir quelque chose ici: http://developer.android.com/training/volley/request.html

est-ce une bonne idée d'utiliser directement ImageRequest au lieu d'ImageLoader? Il semble qu'ImageLoader l'utilise de toute façon en interne. Manque-t-il quelque chose d'important autre que la prise en charge du cache d'ImageLoader?

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);
Lannyf
la source
Il serait très apprécié et plus utile si vous pouviez indiquer pourquoi vous pensez que la question est erronée ou que la solution posée a un problème, au lieu de simplement lui donner un «-1».
lannyf
1
La carte est abstraite. Devrait être HashMap
superuserdo
4

essaye ça

{
    @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;
       }
};
AntuJorge
la source
4

Vous pouvez créer une classe Request personnalisée qui étend le StringRequest et remplacer la méthode getHeaders () à l'intérieur comme ceci:

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;
    }
}
Khashayar Motarjemi
la source
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;
}

}
Navneet Boghani
la source
1

En plus, j'aimerais partager quelque chose que j'ai trouvé concernant Content-Type: En plus de

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

J'ai dû ajouter:

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

Ne me demandez pas pourquoi, j'ai juste pensé que cela pourrait aider certains autres qui ne peuvent pas faire le Content-Typebon ensemble.

Jack
la source
0

Voici la définition des en-têtes à partir de l'exemple github:

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);
M.Kouchi
la source
0

essaye ça

 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);
}
Yigit Yuksel
la source
@Override public Map <String, String> getHeaders () jette AuthFailureError {return headers; }};
Osama Ibrahim
où est l'en-tête ??
Osama Ibrahim
Sur signutare, vous pouvez le définir lorsque vous appelez avec les en
Yigit Yuksel
0

C'est mon code, n'oubliez pas = objet: si ne mettez pas, ne fonctionne pas

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)
Dave Rincon
la source