So legen Sie einen benutzerdefinierten Header in Volley Request fest

104

Wie können benutzerdefinierte Header für eine Volley-Anfrage festgelegt werden? Im Moment gibt es eine Möglichkeit, den Textinhalt für eine POST-Anforderung festzulegen. Ich habe eine einfache GET-Anfrage, aber ich muss die benutzerdefinierten Header zusammen übergeben. Ich sehe nicht, wie die JsonRequest-Klasse dies unterstützt. Ist das überhaupt möglich?

Bianca
quelle
Bitte ändern Sie die akzeptierte Antwort, die aktuell akzeptierte ist falsch.
Esteban

Antworten:

118

Es sieht so aus public Map<String, String> getHeaders(), als würden Sie , definiert inRequest , überschreiben , um die gewünschten HTTP-Header zurückzugeben.

CommonsWare
quelle
4
@ JuanJoséMeleroGómez der Link ist unterbrochen. 404 Nicht gefunden
Milon
Hier ist ein weiteres Beispiel (das Snippet am Ende der Seite): developer.android.com/training/volley/request-custom.html . Die Klasse GsonRequestüberschreibt die Methode getHeaders(), um eine Map mit den Headerparametern zurückzugeben, die Sie im Konstruktor übergeben.
Juan José Melero Gómez
157

Die akzeptierte Antwort mit getParams () dient zum Festlegen von POST-Body-Daten. In der Frage im Titel wurde jedoch gefragt, wie HTTP-Header wie User-Agent festgelegt werden sollen. Wie CommonsWare sagte, überschreiben Sie getHeaders (). Hier ist ein Beispielcode, der den User-Agent auf 'Nintendo Gameboy' und Accept-Language auf 'fr' setzt:

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
quelle
Funktioniert diese Antwort auch für JSONObjectRequest? JSONObjectRequest postRequest = new JSONObjectRequest ...... weil ich das mache und mein getHeaders () nicht aufgerufen wird ... ??? Ich verstehe, dass Sie eine anonyme Klasse erstellen und die Methoden überschreiben. Ich mache genau das nur mit JSONObjectRequest anstelle von StringRequest und mein getHeaders () wird nicht aufgerufen.
JDOaktown
Können wir der getHeaders () -Methode auch "Cookie" hinzufügen? Funktioniert es auch für Post-Anfragen?
Arnab Banerjee
Wohin werde ich den Rest der POST-Daten senden?
Fernando Torres
30

Wenn Sie Daten veröffentlichen müssen, anstatt die Informationen in die URL einzufügen.

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

Wenn Sie die Überschriften in der Anforderung bearbeiten möchten, möchten Sie Folgendes tun:

// 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
quelle
44
Ich habe abgelehnt, da dies überhaupt nicht die Frage ist. Dies dient zum Festlegen von POST-Inhalten und nicht zum Festlegen von benutzerdefinierten HTTP-Headern wie User-Agent. Zh. Atanasov und CommonsWare sind mit ihren getHeadersAntworten richtig .
Georgiecasey
4
Ich habe diese Antwort abgelehnt, weil der Benutzer dies nicht gefragt hat.
Dharmendra Pratap Singh
1
Dies dient zum Hinzufügen von Inhaltsparametern und nicht von Headern. Es sollte wirklich nicht die akzeptierte Antwort sein
Juan Cortés
1
Können Sie sich bitte meine Frage ansehen? Es ist ähnlich, aber ich konnte es nicht richtig machen stackoverflow.com/a/37948318
X09
18

Sie können diese Lösung sehen. Es zeigt, wie Cookies abgerufen / gesetzt werden, aber Cookies sind nur eine der Überschriften in einer Anfrage / Antwort. Sie müssen eine der * Request-Klassen von Volley überschreiben und die erforderlichen Header festlegengetHeaders()


Hier ist die verlinkte Quelle:

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

}}

Und MyApp Klasse:

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

In Kotlin,

Sie müssen die Methode getHeaders () wie folgt überschreiben :

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
quelle
1
Dies ist die einzige Ressource, die ich zum Überschreiben von Headern in Kotlin finden konnte. Danke dir!
Mathew Sonke
@MathewSonke Ich fühle dich Bruder. Übrigens versuchen Sie Retrofit für das Networking in Android.
devDeejay
6

Suchen Sie auch nach einer Lösung für dieses Problem. Sehen Sie hier etwas: http://developer.android.com/training/volley/request.html

Ist es eine gute Idee, ImageRequest direkt anstelle von ImageLoader zu verwenden? ImageLoader verwendet es anscheinend sowieso intern. Fehlt etwas anderes als die Cache-Unterstützung von 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
quelle
Es wäre sehr dankbar und hilfreich, wenn Sie darauf hinweisen könnten, warum Sie der Meinung sind, dass die Frage falsch ist oder die gestellte Lösung ein Problem aufweist, anstatt einfach ein '-1' zu vergeben.
Lannyf
1
Karte ist abstrakt. Sollte HashMap sein
Superuserdo
4

Versuche dies

{
    @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
quelle
4

Sie können eine benutzerdefinierte Request-Klasse erstellen, die die StringRequest erweitert und die darin enthaltene getHeaders () -Methode wie folgt überschreibt:

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
quelle
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
quelle
1

Als Ergänzung möchte ich etwas mitteilen, das ich in Bezug auf Folgendes gefunden habe Content-Type: Oben auf

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

Ich musste hinzufügen:

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

Fragen Sie mich nicht warum, ich dachte nur, es könnte einigen anderen helfen, die das Content-TypeSet nicht richtig machen können.

Jack
quelle
0

Hier setzen Sie Header aus dem Github-Beispiel:

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
quelle
0

Versuche dies

 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
quelle
@Override public Map <String, String> getHeaders () löst AuthFailureError aus {return headers; }};
Osama Ibrahim
Wo ist der Header?
Osama Ibrahim
Auf signutare können Sie es einstellen, wenn Sie mit Map <String, String> -Header aufrufen
Yigit Yuksel
0

Das ist mein Code, nicht vergessen = Objekt: Wenn nicht setzen, funktioniert nicht

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
quelle