83 votes

Volley - paramètres POST/GET

J'ai vu la session Google IO 2013 sur Volley et j'envisage de passer à Volley. Volley prend-il en charge l'ajout de paramètres POST/GET aux requêtes ? Si oui, comment puis-je le faire ?

2 votes

Je n'ai pas vu toute la présentation, mais je suis presque sûr que le GET devrait être réalisable en ajoutant simplement les paramètres à l'URL (ex. http://example.com?param1=val1&param2=val2 )

0 votes

Il semble qu'il n'y ait pas encore de documentation, mais vous pouvez vérifier la source ici. Android.googlesource.com/platform/frameworks/volley/+/master

0 votes

@JJ56 - C'est vrai, mais qu'en est-il des paramètres POST ? J'ai vu le code source mais je n'ai rien trouvé concernant les paramètres POST.

87voto

Ogre_BGR Points 4799

Pour les paramètres GET il y a deux alternatives :

Premier : Comme suggéré dans un commentaire en dessous de la question, vous pouvez simplement utiliser String et remplacer les placeholders des paramètres par leurs valeurs comme :

String uri = String.format("http://somesite.com/some_endpoint.php?param1=%1$s&param2=%2$s",
                           num1,
                           num2);

StringRequest myReq = new StringRequest(Method.GET,
                                        uri,
                                        createMyReqSuccessListener(),
                                        createMyReqErrorListener());
queue.add(myReq);

où num1 et num2 sont des variables de type String qui contiennent vos valeurs.

Deuxièmement : Si vous utilisez HttpClient externe plus récent (4.2.x par exemple) vous pouvez utiliser URIBuilder pour construire votre Uri. L'avantage est que si votre chaîne uri contient déjà des paramètres, il sera plus facile de la passer à la fonction URIBuilder et ensuite utiliser ub.setQuery(URLEncodedUtils.format(getGetParams(), "UTF-8")); pour ajouter vos paramètres supplémentaires. De cette façon, vous n'aurez pas à vérifier si " ?" est déjà ajouté à l'uri ou à en oublier& éliminant ainsi une source d'erreurs potentielles.

Pour les paramètres POST il sera probablement parfois plus facile que la réponse acceptée de le faire comme :

StringRequest myReq = new StringRequest(Method.POST,
                                        "http://somesite.com/some_endpoint.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);

par exemple, pour simplement remplacer le getParams() méthode.

Vous pouvez trouver un exemple fonctionnel (ainsi que de nombreux autres exemples de base de Volley) dans le site Web de l'UE. Projet Andorid Volley Examples .

0 votes

J'ai suivi vos exemples de Volley. Jusqu'à présent, c'est le code Volley le plus utile, mais j'ai un problème avec JsonObjectRequest. J'ai obtenu l'ancienne réponse dans createMyReqSuccessListener jusqu'à ce que je le réinstalle à nouveau. Est-ce que Volley stocke les données dans le cache ? Veuillez suggérer un moyen de le faire.

2 votes

Seules les images sont mises en cache. Veuillez vérifier si un proxy n'intercepte pas vos requêtes. Si les requêtes ont exactement la même URL, il est possible que le proxy renvoie simplement le premier résultat.

0 votes

Vous avez peut-être raison. Mais comment résoudre ce problème ? Est-ce que mettre "header("Cache-Control : no-cache") ; dans le fichier php " cette ligne va aider ?

65voto

AfzalivE Points 554

Dans votre classe Request (qui étend Request), remplacez la méthode getParams(). Vous feriez la même chose pour les en-têtes, en surchargeant simplement getHeaders().

Si vous regardez la classe PostWithBody dans TestRequest.java dans les tests Volley, vous trouverez un exemple. Il ressemble à ceci

public class LoginRequest extends Request<String> {

    // ... other methods go here

    private Map<String, String> mParams;

    public LoginRequest(String param1, String param2, Listener<String> listener, ErrorListener errorListener) {
        super(Method.POST, "http://test.url", errorListener);
        mListener = listener;
        mParams = new HashMap<String, String>();
        mParams.put("paramOne", param1);
        mParams.put("paramTwo", param2);

    }

    @Override
    public Map<String, String> getParams() {
        return mParams;
    }
}

Evan Charlton a eu la gentillesse de réaliser un projet d'exemple rapide pour nous montrer comment utiliser volley. https://github.com/evancharlton/folly/

75 votes

Notez que le getParams est uniquement appelé (par défaut) dans une requête POST ou PUT, mais pas dans une requête GET. Voir la réponse d'Ogre_BGR

2 votes

Je ne peux pas croire que je n'ai jamais remarqué ça jusqu'à maintenant.

0 votes

@AfzalivE, une idée sur la façon de signer la demande API avec OAuth en utilisant le code ci-dessus ?

23voto

LOG_TAG Points 4506

CustomRequest est un moyen de résoudre le problème de JSONObjectRequest de Volley, qui ne peut pas afficher de paramètres comme le paramètre StringRequest

Voici la classe d'aide qui permet d'ajouter des paramètres :

    import java.io.UnsupportedEncodingException;
    import java.util.Map;    
    import org.json.JSONException;
    import org.json.JSONObject;    
    import com.android.volley.NetworkResponse;
    import com.android.volley.ParseError;
    import com.android.volley.Request;
    import com.android.volley.Response;
    import com.android.volley.Response.ErrorListener;
    import com.android.volley.Response.Listener;
    import com.android.volley.toolbox.HttpHeaderParser;

    public class CustomRequest extends Request<JSONObject> {

    private Listener<JSONObject> listener;
    private Map<String, String> params;

    public CustomRequest(String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    public CustomRequest(int method, String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return params;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        listener.onResponse(response);
    }

}

grâce à Greenchiu

0 votes

@WarrenFaith Merci de le signaler, j'ai mis à jour la réponse !

3 votes

Merci beaucoup, j'ai cherché pendant des heures avant de trouver cette solution. C'est tellement bizarre que JSONObjectReuqest getParams() Le remplacement de la fonction ne fonctionne pas.

0 votes

@MohammadWalid Pour info, lisez ceci. stackoverflow.com/questions/16902716/ et essayez d'utiliser le rétrofit ! volley et retrofit peuvent tous deux être utilisés avec okhttp !

10voto

Andrea Motto Points 559

Cette classe d'aide gère les paramètres pour GET y POST demandes :

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;    

import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;

public class CustomRequest extends Request<JSONObject> {
    private int mMethod;
    private String mUrl;
    private Map<String, String> mParams;
    private Listener<JSONObject> mListener;

    public CustomRequest(int method, String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.mMethod = method;
        this.mUrl = url;
        this.mParams = params;
        this.mListener = reponseListener;
    }

@Override
public String getUrl() {
    if(mMethod == Request.Method.GET) {
        if(mParams != null) {
            StringBuilder stringBuilder = new StringBuilder(mUrl);
            Iterator<Map.Entry<String, String>> iterator = mParams.entrySet().iterator();
            int i = 1;
            while (iterator.hasNext()) {
                Map.Entry<String, String> entry = iterator.next();
                if (i == 1) {
                    stringBuilder.append("?" + entry.getKey() + "=" + entry.getValue());
                } else {
                    stringBuilder.append("&" + entry.getKey() + "=" + entry.getValue());
                }
                iterator.remove(); // avoids a ConcurrentModificationException
                i++;
            }
            mUrl = stringBuilder.toString();
        }
    }
    return mUrl;
}

    @Override
    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return mParams;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        mListener.onResponse(response);
    }
}

6voto

Paolo Casciello Points 2630

Traiter avec GET paramètres, j'ai itéré sur la solution "Andrea Motto". Le problème était que Volley appelait GetUrl plusieurs fois et sa solution, utilisant un Iterator, a détruit l'objet Map original. Les appels internes suivants de Volley avaient un objet params vide.

J'ai aussi ajouté l'encodage des paramètres.

Il s'agit d'une utilisation en ligne (pas de sous-classe).

public void GET(String url, Map<String, String> params, Response.Listener<String> response_listener, Response.ErrorListener error_listener, String API_KEY, String stringRequestTag) {
    final Map<String, String> mParams = params;
    final String mAPI_KEY = API_KEY;
    final String mUrl = url;

    StringRequest stringRequest = new StringRequest(
            Request.Method.GET,
            mUrl,
            response_listener,
            error_listener
    ) {
        @Override
        protected Map<String, String> getParams() {
            return mParams;
        }

        @Override
        public String getUrl() {
            StringBuilder stringBuilder = new StringBuilder(mUrl);
            int i = 1;
            for (Map.Entry<String,String> entry: mParams.entrySet()) {
                String key;
                String value;
                try {
                    key = URLEncoder.encode(entry.getKey(), "UTF-8");
                    value = URLEncoder.encode(entry.getValue(), "UTF-8");
                    if(i == 1) {
                        stringBuilder.append("?" + key + "=" + value);
                    } else {
                        stringBuilder.append("&" + key + "=" + value);
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                i++;

            }
            String url = stringBuilder.toString();

            return url;
        }

        @Override
        public Map<String, String> getHeaders() {
            Map<String, String> headers = new HashMap<>();
            if (!(mAPI_KEY.equals(""))) {
                headers.put("X-API-KEY", mAPI_KEY);
            }
            return headers;
        }
    };

    if (stringRequestTag != null) {
        stringRequest.setTag(stringRequestTag);
    }

    mRequestQueue.add(stringRequest);
}

Cette fonction utilise les en-têtes pour transmettre une APIKEY et attribue un TAG à la demande utile pour l'annuler avant son achèvement.

J'espère que cela vous aidera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X