Come inviare una richiesta POST in JSON utilizzando HTTPClient in Android?


111

Sto cercando di capire come POST JSON da Android utilizzando HTTPClient. Ho cercato di capirlo per un po ', ho trovato molti esempi online, ma non riesco a far funzionare nessuno di essi. Credo che ciò sia dovuto alla mia mancanza di conoscenza di JSON / networking in generale. So che ci sono molti esempi là fuori, ma qualcuno potrebbe indicarmi un vero tutorial? Sto cercando una procedura dettagliata con codice e spiegazione del motivo per cui esegui ogni passaggio o di cosa fa quel passaggio. Non è necessario che sia complicato, semplice sarà sufficiente.

Di nuovo, so che ci sono un sacco di esempi là fuori, sto solo cercando un esempio con una spiegazione di cosa sta succedendo esattamente e perché sta facendo in questo modo.

Se qualcuno conosce un buon libro Android su questo argomento, fammelo sapere.

Grazie ancora per l'aiuto @terrance, ecco il codice che ho descritto di seguito

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

Forse puoi pubblicare uno degli esempi che non riesci a far funzionare? Facendo funzionare qualcosa, imparerai come i pezzi si incastrano.
fredw

Risposte:


157

In questa risposta sto usando un esempio pubblicato da Justin Grammens .

Informazioni su JSON

JSON sta per JavaScript Object Notation. In JavaScript è possibile fare riferimento alle proprietà sia in questo modo object1.nameche in questo modo object['name'];. L'esempio dell'articolo utilizza questo bit di JSON.

Le parti
Un oggetto fan con email come chiave e foo@bar.com come valore

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

Quindi l'equivalente dell'oggetto sarebbe fan.email;o fan['email'];. Entrambi avrebbero lo stesso valore di 'foo@bar.com'.

Informazioni su HttpClient Request

Di seguito è riportato ciò che il nostro autore ha utilizzato per effettuare una richiesta HttpClient . Non pretendo di essere affatto un esperto, quindi se qualcuno ha un modo migliore per esprimere un po 'della terminologia si senta libero.

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

Carta geografica

Se non hai familiarità con la Mapstruttura dei dati, dai un'occhiata al riferimento Java Map . In breve, una mappa è simile a un dizionario oa un hash.

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

Sentiti libero di commentare qualsiasi domanda che sorga su questo post o se non ho chiarito qualcosa o se non ho toccato qualcosa su cui sei ancora confuso ... ecc. Qualunque cosa ti venga in mente davvero.

(Eliminerò se Justin Grammens non approva. Ma in caso contrario, ringrazio Justin per essere stato gentile.)

Aggiornare

Sono appena riuscito a ricevere un commento su come utilizzare il codice e mi sono reso conto che c'era un errore nel tipo di ritorno. La firma del metodo era impostata per restituire una stringa ma in questo caso non restituiva nulla. Ho cambiato la firma in HttpResponse e ti rimanderò a questo link su Getting Response Body di HttpResponse la variabile del percorso è l'URL e l'ho aggiornata per correggere un errore nel codice.


Grazie @Terrance. Quindi in una classe diversa sta creando una mappa che ha chiavi e valori diversi che verranno successivamente trasformati in JSONObjects. Ho provato a implementare qualcosa di simile, ma non ho nemmeno esperienza con le mappe, aggiungerò il codice per quello che ho provato a implementare nel mio post originale. Le tue spiegazioni per ciò che stava succedendo sono state fornite da allora e sono riuscito a farlo funzionare creando JSONObjects con nomi e valori codificati. Grazie!

Woot, sono contento di aver potuto aiutare.
Terrance

Justin dice che approva. Dovrebbe avere abbastanza rappresentanti per venire e lasciare un commento lui stesso ormai.
Abizern

Voglio usare questo codice. Come posso procedere? Si prega di specificare qual è la variabile di percorso e cosa deve essere restituito in modo che sul mio terminale Java possa recuperare i dati.
Prateek

3
Non c'è motivo getJsonObjectFromMap(): JSONObject ha un costruttore che accetta Map: developer.android.com/reference/org/json/…
pr1001

41

Ecco una soluzione alternativa alla risposta di @ Terrance. Puoi esternalizzare facilmente la conversione. La libreria Gson fa un lavoro meraviglioso convertendo varie strutture di dati in JSON e viceversa.

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

Simile può essere fatto usando Jackson invece di Gson. Consiglio anche di dare un'occhiata a Retrofit che nasconde molto di questo codice boilerplate per te. Agli sviluppatori più esperti consiglio di provare RxAndroid .


la mia app sta inviando dati tramite il metodo HttpPut. quando il server ha ricevuto la richiesta, risponde come dati json. Non so come ottenere i dati da JSON. dimmelo, ti prego. CODICE .
kongkea

@kongkea Per favore, dai un'occhiata alla libreria GSON . È in grado di analizzare il file JSON in oggetti Java.
JJD

@JJD Finora ciò che suggerisci è di inviare dati al server remoto ed è una bella spiegazione, ma vuoi sapere come analizzare l'oggetto JSON usando il protocollo HTTP. Puoi elaborare la tua risposta anche con l'analisi JSON. Sarà molto utile per tutti coloro che sono nuovi in ​​questo.
AndroidDev

@AndroidDev Si prega di aprire una nuova domanda poiché questa domanda riguarda l'invio di dati dal client al server. Sentiti libero di lasciare un link qui.
JJD

@JJD stai chiamando il metodo astratto execute()e ovviamente non è riuscito
Konstantin Konopko

33

Consiglio di usarlo HttpURLConnectioninvece HttpGet. Come HttpGetgià deprecato nel livello 22 dell'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();
} 

5

Troppo codice per questa attività, controlla questa libreria https://github.com/kodart/Httpzoid Is utilizza GSON internamente e fornisce API che funzionano con gli oggetti. Tutti i dettagli JSON sono nascosti.

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

ottima soluzione, purtroppo questo plugin manca di un supporto graduale: /
electronix384128

3

Esistono due modi per stabilire una connessione HHTP e recuperare i dati da un servizio web RESTFULL. Il più recente è GSON. Ma prima di procedere con GSON è necessario avere un'idea del modo più tradizionale di creare un client HTTP ed eseguire la comunicazione dati con un server remoto. Ho menzionato entrambi i metodi per inviare richieste POST & GET utilizzando 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;
}
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.