Come impostare un'intestazione personalizzata in Volley Request


104

Come si possono impostare intestazioni personalizzate per una richiesta Volley? Al momento, esiste un modo per impostare il contenuto del corpo per una richiesta POST. Ho una semplice richiesta GET, ma devo passare insieme le intestazioni personalizzate. Non vedo come la classe JsonRequest lo supporti. È possibile?


si prega di modificare la risposta accettata, quella attualmente accettata non è corretta.
Esteban

Risposte:


119

Sembra che tu esegua l'override public Map<String, String> getHeaders(), definito inRequest , per restituire le intestazioni HTTP desiderate.


4
@ JuanJoséMeleroGómez il collegamento è interrotto. 404 Non trovato
Milon

Ecco un altro esempio (lo snippet alla fine della pagina): developer.android.com/training/volley/request-custom.html . La classe GsonRequestsovrascrive il metodo getHeaders()per restituire una mappa con i parametri dell'intestazione passati nel costruttore.
Juan José Melero Gómez

157

La risposta accettata con getParams () è per impostare i dati del corpo POST, ma la domanda nel titolo chiedeva come impostare le intestazioni HTTP come User-Agent. Come ha detto CommonsWare, sovrascrivi getHeaders (). Ecco un codice di esempio che imposta lo User-Agent su "Nintendo Gameboy" e Accept-Language su "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);

}

Questa risposta funzionerà anche per JSONObjectRequest? JSONObjectRequest postRequest = new JSONObjectRequest ...... perché lo sto facendo e il mio getHeaders () non viene chiamato ... ??? Capisco che stai creando una classe anonima e sovrascrivendo i metodi. Lo sto facendo solo con JSONObjectRequest invece di StringRequest e il mio getHeaders () non viene chiamato.
JDOaktown

Possiamo aggiungere "Cookie" anche nel metodo getHeaders ()? Funzionerà anche per le richieste di post?
Arnab Banerjee,

Dove invierò il resto dei dati POST?
Fernando Torres

30

Se ciò di cui hai bisogno è pubblicare i dati invece di aggiungere le informazioni nell'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;
}

Se quello che vuoi fare è modificare le intestazioni nella richiesta, questo è quello che vuoi fare:

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

44
Ho downvoted perché questo non è affatto ciò che la domanda ha posto. Serve per impostare il contenuto POST, non per impostare intestazioni HTTP personalizzate come User-Agent. ZH. Atanasov e CommonsWare hanno ragione con le loro getHeadersrisposte.
georgiecasey

4
Ho downvotato questa risposta perché questo non è ciò che l'utente ha chiesto.
Dharmendra Pratap Singh

1
Questo serve per aggiungere parametri di contenuto non intestazioni, spiacente anche downvoted. In realtà non dovrebbe essere la risposta accettata
Juan Cortés

1
Per favore, puoi dare un'occhiata alla mia domanda? E 'simile a questo, ma non ho potuto farlo bene stackoverflow.com/a/37948318
X09

18

Puoi vedere questa soluzione. Mostra come ottenere / impostare i cookie, ma i cookie sono solo una delle intestazioni in una richiesta / risposta. Devi sovrascrivere una delle classi * Request di Volley e impostare le intestazioni richieste ingetHeaders()


Ecco la fonte collegata:

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

}

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

}

7

A Kotlin,

Devi sovrascrivere il metodo getHeaders () come:

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

1
Questa è l'unica risorsa che ho trovato per sovrascrivere le intestazioni in Kotlin. Grazie!
Mathew Sonke

@ MathewSonke ti sento fratello. A proposito, prova Retrofit per il networking in Android.
devDeejay

6

Alla ricerca di una soluzione anche a questo problema. vedere qualcosa qui: http://developer.android.com/training/volley/request.html

è una buona idea usare direttamente ImageRequest invece di ImageLoader? Sembra che ImageLoader lo utilizzi comunque internamente. Manca qualcosa di importante oltre al supporto della cache di 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);

Sarebbe molto apprezzato e più utile se potessi indicare perché ritieni che la domanda sia sbagliata o che la soluzione richiesta abbia un problema, invece di dare semplicemente un "-1".
lannyf

1
La mappa è astratta. Dovrebbe essere HashMap
superuserdo

4

prova questo

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

4

Puoi creare una classe Request personalizzata che estenda StringRequest e sovrascriva il metodo getHeaders () al suo interno in questo modo:

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

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

}

1

Inoltre, vorrei condividere qualcosa che ho trovato riguardo a Content-Type: In cima

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

Ho dovuto aggiungere:

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

Non chiedermi perché, ho solo pensato che potrebbe aiutare altri che non riescono a Content-Typesistemare il set.


0

Ecco l'impostazione delle intestazioni dall'esempio di 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);

0

prova questo

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

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

dov'è l'intestazione ??
Osama Ibrahim

Su signutare, puoi impostarlo quando chiami con le intestazioni Map <String, String>
Yigit Yuksel

0

Questo è il mio codice, non dimenticare = oggetto: se non lo metti non funziona

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.