Bagaimana cara mengirim permintaan POST di JSON menggunakan HTTPClient di Android?

111

Saya mencoba mencari cara untuk POST JSON dari Android dengan menggunakan HTTPClient. Saya telah mencoba mencari tahu hal ini untuk sementara waktu, saya telah menemukan banyak contoh secara online, tetapi saya tidak dapat membuatnya bekerja. Saya yakin ini karena saya kurang memiliki pengetahuan JSON / jaringan secara umum. Saya tahu ada banyak contoh di luar sana tetapi dapatkah seseorang mengarahkan saya ke tutorial yang sebenarnya? Saya mencari proses langkah demi langkah dengan kode dan penjelasan mengapa Anda melakukan setiap langkah, atau apa yang dilakukan langkah itu. Tidak perlu rumit, sederhana saja sudah cukup.

Sekali lagi, saya tahu ada banyak contoh di luar sana, saya hanya benar-benar mencari contoh dengan penjelasan tentang apa yang sebenarnya terjadi dan mengapa hal itu terjadi.

Jika seseorang tahu tentang buku Android yang bagus tentang ini, tolong beri tahu saya.

Sekali lagi terima kasih atas bantuan @terrance, berikut adalah kode yang saya jelaskan di bawah

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();
    }
 }
Gaurav Gandhi
sumber
Mungkin Anda dapat memposting salah satu contoh bahwa Anda tidak dapat bekerja? Dengan membuat sesuatu bekerja, Anda akan belajar bagaimana potongan-potongan itu cocok satu sama lain.
fredw

Jawaban:

157

Dalam jawaban ini saya menggunakan contoh yang diposting oleh Justin Grammens .

Tentang JSON

JSON adalah singkatan dari JavaScript Object Notation. Dalam properti JavaScript dapat direferensikan seperti ini object1.namedan seperti ini object['name'];. Contoh dari artikel menggunakan bit JSON ini.


Objek Fan Parts A dengan email sebagai kunci dan [email protected] sebagai nilai

{
  fan:
    {
      email : '[email protected]'
    }
}

Jadi, ekuivalen objeknya adalah fan.email;atau fan['email'];. Keduanya akan memiliki nilai yang sama '[email protected]'.

Tentang Permintaan HttpClient

Berikut ini adalah apa yang penulis kami gunakan untuk membuat Permintaan HttpClient . Saya tidak mengklaim sebagai ahli dalam semua ini jadi jika ada yang memiliki cara yang lebih baik untuk mengatakan beberapa terminologi, silakan.

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

Peta

Jika Anda tidak terbiasa dengan Mapstruktur datanya, silakan lihat referensi Peta Jawa . Singkatnya, peta mirip dengan kamus atau 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 '[email protected]' 
    //{ fan: { email : '[email protected]' } }

    //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 '[email protected]'  together in map
        holder.put(key, data);
    }
    return holder;
}

Silakan mengomentari setiap pertanyaan yang muncul tentang posting ini atau jika saya belum menjelaskan sesuatu atau jika saya belum menyentuh sesuatu yang Anda masih bingung ... dll apa pun yang muncul di kepala Anda sungguh.

(Saya akan menghapusnya jika Justin Grammens tidak menyetujuinya. Tetapi jika tidak, terima kasih Justin karena telah bersikap dingin tentang hal itu.)

Memperbarui

Saya baru saja mendapat komentar tentang cara menggunakan kode dan menyadari bahwa ada kesalahan dalam tipe pengembalian. Tanda tangan metode disetel untuk mengembalikan string tetapi dalam kasus ini tidak mengembalikan apa pun. Saya mengubah tanda tangan menjadi HttpResponse dan akan mengarahkan Anda ke tautan ini di Mendapatkan Tubuh Tanggapan HttpResponse variabel jalur adalah url dan saya memperbarui untuk memperbaiki kesalahan dalam kode.

Terrance
sumber
Terima kasih @Terrance. Jadi di kelas yang berbeda dia membuat peta yang memiliki kunci dan nilai berbeda yang nantinya akan diubah menjadi JSONObjects. Saya mencoba menerapkan sesuatu yang serupa, tetapi saya juga tidak memiliki pengalaman dengan peta, saya akan menambahkan kode untuk apa yang saya coba terapkan ke posting asli saya. Penjelasan Anda tentang apa yang terjadi sejak itu, dan saya berhasil membuatnya berfungsi dengan membuat JSONObjects dengan nama dan nilai hardcode. Terima kasih!
Woot, Senang bisa membantu.
Terrance
Justin bilang dia setuju. Dia harus memiliki cukup perwakilan untuk datang dan meninggalkan komentar sendiri sekarang.
Abizern
Saya ingin menggunakan kode ini. Bagaimana saya melakukan ini? Harap tentukan apa itu variabel path dan apa yang harus dikembalikan sehingga pada java end saya, saya dapat mengambil data.
Prateek
3
Tidak ada alasan untuk getJsonObjectFromMap(): JSONObject memiliki konstruktor yang membutuhkan Map: developer.android.com/reference/org/json/…
pr1001
41

Berikut adalah solusi alternatif untuk jawaban @ Terrance. Anda dapat dengan mudah melakukan outsourcing konversi. The Gson perpustakaan tidak bekerja indah mengkonversi berbagai struktur data ke dalam JSON dan jalan di sekitar lainnya.

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

Hal serupa dapat dilakukan dengan menggunakan Jackson, bukan Gson. Saya juga merekomendasikan untuk melihat Retrofit yang menyembunyikan banyak kode boilerplate ini untuk Anda. Untuk pengembang yang lebih berpengalaman, saya sarankan untuk mencoba RxAndroid .

JJD
sumber
aplikasi saya mengirim data melalui metode HttpPut. ketika server mendapat permintaan, itu membalas sebagai data json. Saya tidak tahu bagaimana cara mendapatkan data dari json. tolong beritahu aku. KODE .
kongkea
@kongkea Silakan lihat ke perpustakaan GSON . Ia mampu mengurai file JSON menjadi objek Java.
JJD
@JJD Sejauh ini yang Anda sarankan adalah mengirim data ke server jarak jauh dan penjelasannya bagus, tetapi ingin tahu cara mengurai objek JSON menggunakan protokol HTTP. Bisakah Anda menguraikan jawaban Anda dengan penguraian JSON juga. Ini akan sangat membantu bagi semua orang yang baru dalam hal ini.
AndroidDev
@AndroidDev Silakan buka pertanyaan baru karena pertanyaan ini tentang pengiriman data dari klien ke server. Jangan ragu untuk menjatuhkan tautan di sini.
JJD
@JJD Anda memanggil metode abstrak execute()dan tentu saja gagal
Konstantin Konopko
33

Saya merekomendasikan menggunakan ini HttpURLConnectionsebagai gantinya HttpGet. Seperti HttpGetyang sudah tidak digunakan lagi di Android API level 22.

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

Terlalu banyak kode untuk tugas ini, periksa pustaka ini https://github.com/kodart/Httpzoid Is menggunakan GSON secara internal dan menyediakan API yang berfungsi dengan objek. Semua detail JSON disembunyikan.

Http http = HttpFactory.create(context);
http.get("http://example.com/users")
    .handler(new ResponseHandler<User[]>() {
        @Override
        public void success(User[] users, HttpResponse response) {
        }
    }).execute();
Arthur
sumber
solusi hebat, sayangnya plugin ini tidak memiliki dukungan gradle: /
electronix384128
3

Ada beberapa cara untuk membuat koneksi HHTP dan mengambil data dari layanan web RESTFULL. Yang terbaru adalah GSON. Tetapi sebelum Anda melanjutkan ke GSON, Anda harus memiliki beberapa gagasan tentang cara paling tradisional untuk membuat Klien HTTP dan melakukan komunikasi data dengan server jarak jauh. Saya telah menyebutkan kedua metode untuk mengirim permintaan POST & GET menggunakan 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;
}
Mike Clark
sumber