2016-09-17 3 views
-1

Wie kann ich bei jeder beliebigen Volley-Anfrage Response-Header und statusCode erfassen, unabhängig vom Erfolg/Fehler?Header und Statuscode von Volley erhalten?

Versuche/Ideen:

:

@Override 
protected Response parseNetworkResponse(NetworkResponse response) { 
    return Response.success(response.statusCode, 
          HttpHeaderParser.parseCacheHeaders(response)); 
} 

Edit: zu klären, ich habe eine einfache tuple Klasse bekam:

public final class ErrResStatusHeaders<E, R> { 
    public final E error; 
    public final R result; 
    public final int statusCode; 
    public final Map<String, String> headers; 

Und in meinem Activity:

@Override 
protected ErrResStatusHeaders<String,JSONObject> doInBackground(Void... params) { 
    // futures instantiated and utility function(s) called here 

[...] 

@Override 
protected void onPostExecute(final ErrResStatusHeaders<String,JSONObject> er_res) 

Beispiel Nutzenfunktion Signatur:

public ErrResStatusHeaders<String, JSONObject> register_or_login(
           final HashMap<String, String> data, 
           final RequestFuture<JSONObject> register_future, 
           final RequestFuture<JSONObject> login_future) { 
+0

Wäre toll, wenn es unabhängig von 'JSONObject' oder' String' oder keinem Körper funktioniert (zB: irgendeine andere HTTP-Methode), und das mit 'RequestFuture' zulässt :) –

Antwort

0
String uri = "http://whatevergoeshere.com"; 
StringRequest stringRequest = new StringRequest("uri", responseListener, errorListener) { 
    @Override 
    protected Response<String> parseNetworkResponse(NetworkResponse response) { 
     Log.d("TEST", "Headers size:" + response.headers.size()); 
     return super.parseNetworkResponse(response); 
    } 

    @Override 
    protected VolleyError parseNetworkError(VolleyError volleyError) { 
     if (volleyError.networkResponse != null && volleyError.networkResponse.headers != null) 
      Log.d("TEST", "Headers size:" + volleyError.networkResponse.headers.size()); 
     return super.parseNetworkError(volleyError); 
    } 
}; 

Nun, sieht aus wie die Frage ziemlich viel verändert, so ist hier meine bearbeitet Antwort:

Sie eine benutzerdefinierte Anfrage Unterklasse wie folgt verwenden können:

public class RawRequest extends Request<NetworkResponse> { 
    private final Response.Listener<NetworkResponse> mListener; 

    /** 
    * Creates a new GET request. 
    * 
    * @param url URL to fetch the string at 
    * @param listener Listener to receive the String response 
    * @param errorListener Error listener, or null to ignore errors 
    */ 
    public RawRequest(String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) { 
     this(Method.GET, url, listener, errorListener); 
    } 

    /** 
    * Creates a new request with the given method. 
    * 
    * @param method the request {@link Method} to use 
    * @param url URL to fetch the string at 
    * @param listener Listener to receive the String response 
    * @param errorListener Error listener, or null to ignore errors 
    */ 
    public RawRequest(int method, String url, Response.Listener<NetworkResponse> listener, 
         Response.ErrorListener errorListener) { 
     super(method, url, errorListener); 
     mListener = listener; 
    } 

    @Override 
    protected Response parseNetworkResponse(NetworkResponse response) { 
     return Response.success(response, HttpHeaderParser.parseCacheHeaders(response)); 
    } 

    @Override 
    protected void deliverResponse(NetworkResponse response) { 
     mListener.onResponse(response); 
    } 
} 

es dann in einer anderen Klasse verwenden:

String uri = "http://whatevergoeshere.com"; 
RequestFuture<NetworkResponse> future = RequestFuture.newFuture(); 
RawRequest rawRequest = new RawRequest("uri", future, future); 

Aber der Nachteil hier ist offensichtlich jetzt müssen Sie die gesamte Antwort selbst analysieren. Sie können das vermeiden, indem Sie eine benutzerdefinierte Listener-Schnittstelle schreiben, die die analysierte Antwort (sei es JSON oder String oder Bild) sowie die Header als zweites Argument übergibt. Dann müssten Sie Ihre eigene RequestFuture-Klasse schreiben, um dies zu unterstützen.

Ehrlich gesagt, würde ich vorschlagen, einen anderen Ansatz außerhalb einer AsyncTask dafür zu versuchen. Volley kann die Anfragen bereits asynchron verarbeiten.

+0

Danke, aber gibt es einen Weg dazu Tun Sie dies, so dass es in der 'OnPostExecute' Callback in meiner Aktivität funktioniert? - Der Volley-Stuff läuft in 'doInBackground', speziell in einer Utility-Klasse, die dort im' return' aufgerufen wird.Also brauche ich irgendwie die Netzwerkantwort für alle Anfragen. Ob normal oder über eine Zukunft abgerollt. –

+0

Die Antwort wurde aktualisiert, aber ich würde wirklich vorschlagen, den gesamten Ansatz zu ändern, anstatt Volley innerhalb von AsyncTask zu verwenden. – AfzalivE

+0

Via Telefon, aber von einem Blick, der aussieht wie ['ServerStatusRequestObject'] (http://www.b2cloud.com.au/tutorial/getting-a-server-response-status-200-from-android-volley-library) . Ihre Idee, eine neue 'RequestFuture' zu schreiben, et al. scheint gesund zu sein. Werde es ausprobieren, wenn ich zurück bin. –

Verwandte Themen