Android'de HTTPClient kullanarak JSON'da POST isteği nasıl gönderilir?


111

HTTPClient kullanarak Android'den JSON'u nasıl POST yapacağımı anlamaya çalışıyorum. Bunu bir süredir anlamaya çalışıyorum, internette pek çok örnek buldum, ancak hiçbirinin çalışmasını sağlayamıyorum. Bunun genel olarak JSON / ağ bilgisi eksikliğimden kaynaklandığına inanıyorum. Orada birçok örnek olduğunu biliyorum ama biri beni gerçek bir öğreticiye yönlendirebilir mi? Kod ve her adımı neden yaptığınızı veya bu adımın ne yaptığını açıklayan adım adım bir işlem arıyorum. Karmaşık olmasına gerek yok, basit yeterli olacaktır.

Yine, orada bir sürü örnek olduğunu biliyorum, sadece tam olarak ne olduğu ve neden bu şekilde yaptığına dair bir açıklama içeren bir örnek arıyorum.

Birisi bununla ilgili iyi bir Android kitabı biliyorsa, lütfen bana bildirin.

@Terrance yardımı için tekrar teşekkürler, işte aşağıda anlattığım kod

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

Belki çalışamayacağın örneklerden birini gönderebilirsin? Bir şeyi çalıştırarak, parçaların nasıl birbirine uyduğunu öğrenirsiniz.
fredw

Yanıtlar:


157

Bu cevapta Justin Grammens tarafından yayınlanan bir örnek kullanıyorum .

JSON hakkında

JSON, JavaScript Object Notation anlamına gelir. JavaScript'inizde özellikler böyle hem başvurulabilir object1.nameve bunun gibi object['name'];. Makaledeki örnek bu JSON parçasını kullanır.

Parçalar
Anahtar olarak e-posta ve değer olarak foo@bar.com olan bir hayran nesnesi

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

Yani nesne eşdeğeri fan.email;veya olacaktır fan['email'];. Her ikisi de aynı değere sahip olacaktır 'foo@bar.com'.

HttpClient İsteği Hakkında

Aşağıdaki, yazarımızın bir HttpClient İsteği yapmak için kullandığı şeydir . Tüm bu konularda uzman olduğumu iddia etmiyorum, bu yüzden eğer herhangi biri terminolojinin bir kısmını daha iyi bir şekilde ifade edebiliyorsa, kendinizi özgür hissedin.

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

Harita

MapVeri yapısına aşina değilseniz, lütfen Java Haritası referansına bir göz atın . Kısacası, bir harita bir sözlüğe veya bir hash'e benzer.

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

Lütfen bu gönderi hakkında ortaya çıkan herhangi bir soru hakkında yorum yapmaktan çekinmeyin veya bir şeyi netleştirmediysem veya hala kafanızın karıştığı bir şeye değinmediysem ... vs gerçekten kafanızda ne olursa olsun.

(Justin Grammens onaylamazsa indiririm. Ama değilse o zaman Justin'e soğukkanlı davrandığı için teşekkür ederim.)

Güncelleme

Kodun nasıl kullanılacağına dair bir yorum almaktan mutluluk duydum ve dönüş türünde bir hata olduğunu fark ettim. Yöntem imzası bir dize döndürecek şekilde ayarlandı, ancak bu durumda hiçbir şey döndürmedi. İmzayı HttpResponse olarak değiştirdim ve sizi HttpResponse'un Yanıt Gövdesi'ndeki bu bağlantıya yönlendireceğim , yol değişkeni url'dir ve koddaki bir hatayı düzeltmek için güncelledim.


Teşekkürler @Terrance. Yani farklı bir sınıfta, daha sonra JSONObjects'e dönüştürülecek olan farklı anahtarlara ve değerlere sahip bir harita oluşturuyor. Benzer bir şeyi uygulamayı denedim, ancak haritalarla ilgili deneyimim de yok, uygulamaya çalıştığım şeyin kodunu orijinal yazıma ekleyeceğim. O zamandan beri neler olup bittiğine dair açıklamalarınız ve kodlanmış isimler ve değerlerle JSONObjects oluşturarak bunu çalıştırmayı başardım. Teşekkürler!

Woot, yardımcı olabildiğime sevindim.
Terrance

Justin onayladığını söylüyor. Şimdiye kadar gelip bir yorum bırakacak kadar itibarı olmalı.
Abizern

Bu kodu kullanmak istiyorum. Bunu nasıl yapacağım? Lütfen yol değişkeninin ne olduğunu ve neyin döndürülmesi gerektiğini belirtin, böylece java ucumda verileri alabileyim.
Prateek

3
Bunun bir nedeni yok getJsonObjectFromMap(): JSONObject, bir Map: developer.android.com/reference/org/json/…
pr1001

41

İşte @ Terrance'ın cevabına alternatif bir çözüm. Dönüşümü kolaylıkla dış kaynak olarak kullanabilirsiniz. GSON kütüphane JSON içine çeşitli veri yapıları ve tersi dönüştürme harika çalışır.

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

Gson yerine Jackson kullanılarak benzer şekilde yapılabilir . Ayrıca , sizin için bu standart kodun çoğunu gizleyen Retrofit'e bir göz atmanızı da tavsiye ederim. Daha deneyimli geliştiriciler için RxAndroid'i denemenizi tavsiye ederim .


Uygulamam HttpPut yöntemiyle veri gönderiyor. sunucu istek aldığında json verisi olarak yanıt veriyor. JSON'dan nasıl veri alınacağını bilmiyorum. lütfen söyle bana. KOD .
kongkea

@kongkea Lütfen GSON kitaplığına bir göz atın . JSON dosyasını Java nesnelerine ayrıştırabilir.
JJD

@JJD Şimdiye kadar önerdiğiniz şey uzak sunucuya veri göndermek ve bu güzel bir açıklama, ancak JSON nesnesinin HTTP protokolünü kullanarak nasıl ayrıştırılacağını bilmek istiyorum. Cevabınızı JSON ayrıştırma ile de detaylandırabilir misiniz? Bunda yeni olan herkes için çok yardımcı olacak.
AndroidDev

@AndroidDev Bu soru istemciden sunucuya veri göndermekle ilgili olduğundan, lütfen yeni bir soru açın . Buraya bir bağlantı bırakmaktan çekinmeyin.
JJD

@JJD, soyut yöntemi execute()
arıyorsun

33

HttpURLConnectionOnun yerine bunu kullanmanızı tavsiye ederim HttpGet. As HttpGetzaten Android API düzeyinde 22'de kaldırılmıştır.

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

Bu görev için çok fazla kod var, bu kitaplığa göz atın https://github.com/kodart/Httpzoid Dahili olarak GSON kullanır ve nesnelerle çalışan API sağlar. Tüm JSON ayrıntıları gizlidir.

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

harika çözüm, maalesef bu eklenti gradle desteğinden yoksun: /
Electronix384128

3

HHTP bağlantısı kurmanın ve bir RESTFULL web hizmetinden veri almanın birkaç yolu vardır. En güncel olanı GSON'dur. Ancak GSON'a geçmeden önce, bir HTTP İstemcisi oluşturmanın en geleneksel yolu hakkında bir fikriniz olmalı ve uzak bir sunucuyla veri iletişimi gerçekleştirmelisiniz. HTTPClient kullanarak POST ve GET istekleri göndermenin her iki yönteminden de bahsetmiştim.

/**
 * 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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.