111 votes

Comment envoyer une requête POST en JSON avec HTTPClient sous Android ?

J'essaie de comprendre comment POST JSON depuis Android en utilisant HTTPClient. Cela fait un moment que j'essaie de résoudre ce problème. J'ai trouvé de nombreux exemples en ligne, mais aucun d'entre eux ne fonctionne. Je pense que cela est dû à mon manque de connaissances sur JSON et les réseaux en général. Je sais qu'il existe de nombreux exemples, mais quelqu'un pourrait-il m'indiquer un véritable tutoriel ? Je cherche un processus étape par étape avec du code et une explication de la raison pour laquelle vous faites chaque étape, ou de ce que fait cette étape. Il n'est pas nécessaire que ce soit compliqué, le plus simple suffira.

Encore une fois, je sais qu'il existe une tonne d'exemples, mais je cherche simplement un exemple avec une explication de ce qui se passe exactement et pourquoi cela se passe ainsi.

Si quelqu'un connaît un bon livre sur Android à ce sujet, faites-le moi savoir.

Merci encore pour l'aide @terrance, voici le code que j'ai décrit ci-dessous

public void shNameVerParams() throws Exception{
     String path = //removed
     HashMap  params = new HashMap();

     params.put(new String("Name"), "Value"); 
     params.put(new String("Name"), "Value");

     try {
        HttpClient.SendHttpPost(path, params);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
 }

157voto

Terrance Points 5384

Dans cette réponse, j'utilise un exemple posté par Justin Grammens .

À propos de JSON

JSON est l'abréviation de JavaScript Object Notation. En JavaScript, les propriétés peuvent être référencées de la manière suivante object1.name et comme ceci object['name']; . L'exemple de l'article utilise ce bout de JSON.

Les pièces
Un objet fan avec email comme clé et foo@bar.com comme valeur.

{
  fan:
    {
      email : 'foo@bar.com'
    }
}

L'équivalent objet serait donc fan.email; ou fan['email']; . Les deux auraient la même valeur de 'foo@bar.com' .

A propos de la requête HttpClient

Voici ce que notre auteur a utilisé pour faire un Demande HttpClient . Je ne prétends pas être un expert en la matière, donc si quelqu'un a une meilleure façon de formuler la terminologie, n'hésitez pas.

public static HttpResponse makeRequest(String path, Map params) throws Exception 
{
    //instantiates httpclient to make request
    DefaultHttpClient httpclient = new DefaultHttpClient();

    //url with the post data
    HttpPost httpost = new HttpPost(path);

    //convert parameters into JSON object
    JSONObject holder = getJsonObjectFromMap(params);

    //passes the results to a string builder/entity
    StringEntity se = new StringEntity(holder.toString());

    //sets the post request as the resulting string
    httpost.setEntity(se);
    //sets a request header so the page receving the request
    //will know what to do with it
    httpost.setHeader("Accept", "application/json");
    httpost.setHeader("Content-type", "application/json");

    //Handles what is returned from the page 
    ResponseHandler responseHandler = new BasicResponseHandler();
    return httpclient.execute(httpost, responseHandler);
}

Carte

Si vous n'êtes pas familier avec le Map veuillez jeter un coup d'œil à la structure de données Référence à la carte Java . En bref, une carte est similaire à un dictionnaire ou à un hachage.

private static JSONObject getJsonObjectFromMap(Map params) throws JSONException {

    //all the passed parameters from the post request
    //iterator used to loop through all the parameters
    //passed in the post request
    Iterator iter = params.entrySet().iterator();

    //Stores JSON
    JSONObject holder = new JSONObject();

    //using the earlier example your first entry would get email
    //and the inner while would get the value which would be 'foo@bar.com' 
    //{ fan: { email : 'foo@bar.com' } }

    //While there is another entry
    while (iter.hasNext()) 
    {
        //gets an entry in the params
        Map.Entry pairs = (Map.Entry)iter.next();

        //creates a key for Map
        String key = (String)pairs.getKey();

        //Create a new map
        Map m = (Map)pairs.getValue();   

        //object for storing Json
        JSONObject data = new JSONObject();

        //gets the value
        Iterator iter2 = m.entrySet().iterator();
        while (iter2.hasNext()) 
        {
            Map.Entry pairs2 = (Map.Entry)iter2.next();
            data.put((String)pairs2.getKey(), (String)pairs2.getValue());
        }

        //puts email and 'foo@bar.com'  together in map
        holder.put(key, data);
    }
    return holder;
}

_

N'hésitez pas à commenter toute question relative à cet article, si je n'ai pas été clair ou si je n'ai pas abordé un sujet qui vous laisse perplexe... ou tout ce qui vous passe par la tête.

_

(Je le retirerai si Justin Grammens n'approuve pas. Mais sinon, merci à Justin d'être cool à ce sujet).

Mise à jour

J'ai reçu par hasard un commentaire sur la façon d'utiliser le code et j'ai réalisé qu'il y avait une erreur dans le type de retour. La signature de la méthode était configurée pour retourner une chaîne de caractères mais dans ce cas, elle ne retournait rien. J'ai changé la signature en HttpResponse et je vous renvoie à ce lien sur Obtenir le corps de la réponse de HttpResponse la variable path est l'url et j'ai mis à jour pour corriger une erreur dans le code.

41voto

JJD Points 7539

Voici une solution alternative à la réponse de @Terrance. Vous pouvez facilement externaliser la conversion. Le site Bibliothèque de Gson fait un travail formidable en convertissant diverses structures de données en JSON et vice-versa.

public static void execute() {
    Map<String, String> comment = new HashMap<String, String>();
    comment.put("subject", "Using the GSON library");
    comment.put("message", "Using libraries is convenient.");
    String json = new GsonBuilder().create().toJson(comment, Map.class);
    makeRequest("http://192.168.0.1:3000/post/77/comments", json);
}

public static HttpResponse makeRequest(String uri, String json) {
    try {
        HttpPost httpPost = new HttpPost(uri);
        httpPost.setEntity(new StringEntity(json));
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Content-type", "application/json");
        return new DefaultHttpClient().execute(httpPost);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

On peut faire de même en utilisant Jackson au lieu de Gson. Je vous recommande également de jeter un coup d'œil à Rétrofit qui cache une grande partie de ce code passe-partout pour vous. Pour les développeurs plus expérimentés, je recommande d'essayer RxAndroid .

33voto

Egis Points 179

Je recommande d'utiliser ce HttpURLConnection au lieu de HttpGet . Comme HttpGet est déjà déprécié dans le niveau 22 de l'API Android.

HttpURLConnection httpcon;  
String url = null;
String data = null;
String result = null;
try {
  //Connect
  httpcon = (HttpURLConnection) ((new URL (url).openConnection()));
  httpcon.setDoOutput(true);
  httpcon.setRequestProperty("Content-Type", "application/json");
  httpcon.setRequestProperty("Accept", "application/json");
  httpcon.setRequestMethod("POST");
  httpcon.connect();

  //Write       
  OutputStream os = httpcon.getOutputStream();
  BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
  writer.write(data);
  writer.close();
  os.close();

  //Read        
  BufferedReader br = new BufferedReader(new InputStreamReader(httpcon.getInputStream(),"UTF-8"));

  String line = null; 
  StringBuilder sb = new StringBuilder();         

  while ((line = br.readLine()) != null) {  
    sb.append(line); 
  }         

  br.close();  
  result = sb.toString();

} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

5voto

Arthur Points 224

Trop de code pour cette tâche, consultez cette bibliothèque. https://github.com/kodart/Httpzoid Il utilise GSON en interne et fournit une API qui fonctionne avec des objets. Tous les détails JSON sont cachés.

Http http = HttpFactory.create(context);
http.get("http://example.com/users")
    .handler(new ResponseHandler<User[]>() {
        @Override
        public void success(User[] users, HttpResponse response) {
        }
    }).execute();

3voto

Mike Clark Points 1774

Il existe plusieurs façons d'établir une connexion HHTP et d'extraire des données d'un service web RESTFULL. La plus récente est GSON. Mais avant de passer à GSON, vous devez avoir une idée de la manière la plus traditionnelle de créer un client HTTP et de communiquer des données avec un serveur distant. J'ai mentionné les deux méthodes pour envoyer des requêtes POST et GET en utilisant HTTPClient.

/**
 * This method is used to process GET requests to the server.
 * 
 * @param url 
 * @return String
 * @throws IOException
 */
public static String connect(String url) throws IOException {

    HttpGet httpget = new HttpGet(url);
    HttpResponse response;
    HttpParams httpParameters = new BasicHttpParams();
    // Set the timeout in milliseconds until a connection is established.
    // The default value is zero, that means the timeout is not used. 
    int timeoutConnection = 60*1000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    // Set the default socket timeout (SO_TIMEOUT) 
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 60*1000;

    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
    HttpClient httpclient = new DefaultHttpClient(httpParameters);
    try {

        response = httpclient.execute(httpget);

        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            result = convertStreamToString(instream);
            //instream.close();
        }
    } 
    catch (ClientProtocolException e) {
        Utilities.showDLog("connect","ClientProtocolException:-"+e);
    } catch (IOException e) {
        Utilities.showDLog("connect","IOException:-"+e); 
    }
    return result;
}

 /**
 * This method is used to send POST requests to the server.
 * 
 * @param URL
 * @param paramenter
 * @return result of server response
 */
static public String postHTPPRequest(String URL, String paramenter) {       

    HttpParams httpParameters = new BasicHttpParams();
    // Set the timeout in milliseconds until a connection is established.
    // The default value is zero, that means the timeout is not used. 
    int timeoutConnection = 60*1000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    // Set the default socket timeout (SO_TIMEOUT) 
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 60*1000;

    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
    HttpClient httpclient = new DefaultHttpClient(httpParameters);
    HttpPost httppost = new HttpPost(URL);
    httppost.setHeader("Content-Type", "application/json");
    try {
        if (paramenter != null) {
            StringEntity tmp = null;
            tmp = new StringEntity(paramenter, "UTF-8");
            httppost.setEntity(tmp);
        }
        HttpResponse httpResponse = null;
        httpResponse = httpclient.execute(httppost);
        HttpEntity entity = httpResponse.getEntity();
        if (entity != null) {
            InputStream input = null;
            input = entity.getContent();
            String res = convertStreamToString(input);
            return res;
        }
    } 
     catch (Exception e) {
        System.out.print(e.toString());
    }
    return null;
}

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