Làm cách nào để gửi yêu cầu POST trong JSON bằng HTTPClient trong Android?


111

Tôi đang cố gắng tìm cách ĐĂNG JSON từ Android bằng cách sử dụng HTTPClient. Tôi đã cố gắng tìm ra điều này trong một thời gian, tôi đã tìm thấy rất nhiều ví dụ trực tuyến, nhưng tôi không thể làm cho bất kỳ ví dụ nào trong số đó hoạt động. Tôi tin rằng điều này là do tôi thiếu kiến ​​thức về JSON / mạng nói chung. Tôi biết có rất nhiều ví dụ nhưng ai đó có thể chỉ cho tôi một hướng dẫn thực tế không? Tôi đang tìm kiếm quy trình từng bước với mã và giải thích lý do tại sao bạn thực hiện từng bước hoặc bước đó làm gì. Nó không cần phải là một ý chí phức tạp, đơn giản là đủ.

Một lần nữa, tôi biết có rất nhiều ví dụ ngoài kia, tôi chỉ thực sự tìm kiếm một ví dụ với lời giải thích chính xác những gì đang xảy ra và tại sao nó lại làm theo cách đó.

Nếu ai đó biết về một cuốn sách Android hay về điều này, vui lòng cho tôi biết.

Cảm ơn một lần nữa vì sự trợ giúp @terrance, đây là mã tôi mô tả bên dưới

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

Có lẽ bạn có thể đăng một trong những ví dụ mà bạn không thể làm việc? Bằng cách làm cho thứ gì đó hoạt động, bạn sẽ học được cách các mảnh ghép lại với nhau.
fredw

Câu trả lời:


157

Trong câu trả lời này, tôi đang sử dụng một ví dụ được đăng bởi Justin Grammens .

Về JSON

JSON là viết tắt của JavaScript Object Notation. Trong JavaScript thuộc tính có thể được tham chiếu cả như thế này object1.namevà như thế này object['name'];. Ví dụ từ bài viết sử dụng bit JSON này.

Các phần
Một đối tượng người hâm mộ với email làm khóa và foo@bar.com làm giá trị

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

Vì vậy, đối tượng tương đương sẽ là fan.email;hoặc fan['email'];. Cả hai sẽ có cùng giá trị 'foo@bar.com'.

Giới thiệu về Yêu cầu HttpClient

Sau đây là những gì tác giả của chúng tôi sử dụng để đưa ra Yêu cầu HttpClient . Tôi không tự nhận mình là một chuyên gia về điều này vì vậy nếu ai có cách tốt hơn để sử dụng một số thuật ngữ thì cứ tự nhiên.

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

Bản đồ

Nếu bạn không quen với Mapcấu trúc dữ liệu, vui lòng xem tài liệu tham khảo Bản đồ Java . Tóm lại, một bản đồ tương tự như một từ điển hoặc một hàm băm.

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

Vui lòng bình luận về bất kỳ câu hỏi nào nảy sinh về bài đăng này hoặc nếu tôi chưa nói rõ điều gì hoặc nếu tôi chưa chạm vào điều gì đó mà bạn vẫn còn bối rối về ... vv bất cứ điều gì xuất hiện trong đầu bạn thực sự.

(Tôi sẽ gỡ xuống nếu Justin Grammens không chấp thuận. Nhưng nếu không, thì cảm ơn Justin vì đã rất bình tĩnh.)

Cập nhật

Tôi chỉ tình cờ nhận được nhận xét về cách sử dụng mã và nhận ra rằng có một lỗi trong kiểu trả về. Chữ ký phương thức được đặt để trả về một chuỗi nhưng trong trường hợp này, nó không trả về bất cứ thứ gì. Tôi đã thay đổi chữ ký thành HttpResponse và sẽ giới thiệu cho bạn liên kết này trên Cơ quan phản hồi của HttpResponse , biến đường dẫn là url và tôi đã cập nhật để sửa lỗi trong mã.


Cảm ơn @Terrance. Vì vậy, trong một lớp khác, anh ta đang tạo một bản đồ có các khóa và giá trị khác nhau mà sau này sẽ được chuyển thành JSONObjects. Tôi đã thử triển khai một cái gì đó tương tự, nhưng tôi cũng không có kinh nghiệm với bản đồ, tôi sẽ thêm mã cho những gì tôi đã thử triển khai vào bài đăng ban đầu của mình. Giải thích của bạn cho những gì đã xảy ra kể từ đó và tôi đã thành công trong việc làm cho nó hoạt động bằng cách tạo JSONObjects với các tên và giá trị được mã hóa cứng. Cảm ơn!

Woot, rất vui vì tôi có thể giúp.
Terrance

Justin nói rằng anh ấy chấp thuận. Anh ấy nên có đủ đại diện để đến và để lại bình luận cho mình vào lúc này.
Abizern

Tôi muốn sử dụng mã này. Làm thế nào để tôi đi về điều này? Vui lòng chỉ định biến đường dẫn là gì và những gì phải được trả lại để trên phần cuối java của tôi, tôi có thể tìm nạp dữ liệu.
Prateek

3
Không có lý do gì cho getJsonObjectFromMap(): JSONObject có một hàm tạo nhận Map: developer.android.com/reference/org/json/…
pr1001

41

Đây là một giải pháp thay thế cho câu trả lời của @ Terrance. Bạn có thể dễ dàng thuê ngoài chuyển đổi. Các thư viện Gson làm việc tuyệt vời chuyển đổi cấu trúc dữ liệu khác nhau vào JSON và xung quanh theo cách khác.

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

Tương tự có thể được thực hiện bằng cách sử dụng Jackson thay vì Gson. Tôi cũng khuyên bạn nên xem qua Retrofit ẩn rất nhiều mã soạn sẵn này cho bạn. Đối với các nhà phát triển có kinh nghiệm hơn, tôi khuyên bạn nên dùng thử RxAndroid .


ứng dụng của tôi đang gửi dữ liệu qua phương thức HttpPut. khi máy chủ nhận được yêu cầu, nó sẽ trả lời dưới dạng dữ liệu json. Tôi không biết làm thế nào để lấy dữ liệu từ json. xin vui lòng cho tôi biết. MÃ SỐ .
kongkea

@kongkea Vui lòng xem thư viện GSON . Nó có khả năng phân tích cú pháp tệp JSON thành các đối tượng Java.
JJD

@JJD Cho đến nay, những gì bạn đề xuất là gửi dữ liệu đến máy chủ từ xa và một lời giải thích hay về nó, nhưng bạn muốn biết cách phân tích cú pháp đối tượng JSON bằng giao thức HTTP. Bạn cũng có thể giải thích câu trả lời của mình bằng cách phân tích cú pháp JSON. Nó sẽ rất hữu ích cho tất cả những người mới trong lĩnh vực này.
AndroidDev

@AndroidDev Vui lòng mở một câu hỏi mới vì câu hỏi này là về việc gửi dữ liệu từ máy khách đến máy chủ. Hãy thả một liên kết ở đây.
JJD

@JJD bạn đang gọi phương pháp trừu tượng execute()và nó được thất bại tất nhiên
Konstantin Konopko

33

Tôi khuyên bạn nên sử dụng cái này HttpURLConnectionthay thế HttpGet. Như HttpGetđã không còn được dùng trong API Android cấp 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();
} 

5

Quá nhiều mã cho tác vụ này, hãy xem thư viện này https://github.com/kodart/Httpzoid Là sử dụng GSON nội bộ và cung cấp API hoạt động với các đối tượng. Tất cả chi tiết JSON đều bị ẩn.

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

giải pháp tuyệt vời, rất tiếc là plugin này thiếu hỗ trợ gradle: /
electronix384128

3

Có một số cách để thiết lập kết nối Khu CNC Hòa Lạc và tìm nạp dữ liệu từ dịch vụ web RESTFULL. Gần đây nhất là GSON. Nhưng trước khi tiếp tục với GSON, bạn phải có một số ý tưởng về cách truyền thống nhất để tạo HTTP Client và thực hiện giao tiếp dữ liệu với một máy chủ từ xa. Tôi đã đề cập đến cả hai phương pháp gửi yêu cầu POST & GET bằng 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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.