จะส่งคำขอ POST ใน JSON โดยใช้ HTTPClient ใน Android ได้อย่างไร


111

ฉันกำลังพยายามหาวิธีโพสต์ JSON จาก Android โดยใช้ HTTPClient ฉันพยายามหาสิ่งนี้มาระยะหนึ่งแล้วฉันพบตัวอย่างมากมายทางออนไลน์ แต่ฉันไม่สามารถใช้งานได้เลย ฉันเชื่อว่านี่เป็นเพราะการขาดความรู้ JSON / เครือข่ายโดยทั่วไปของฉัน ฉันรู้ว่ามีตัวอย่างมากมาย แต่อาจมีใครชี้ให้ฉันดูบทช่วยสอนจริงได้ไหม ฉันกำลังมองหากระบวนการทีละขั้นตอนพร้อมรหัสและคำอธิบายว่าทำไมคุณถึงทำแต่ละขั้นตอนหรือว่าขั้นตอนนั้นทำอะไร ไม่จำเป็นต้องซับซ้อนเรียบง่ายก็พอเพียง

อีกครั้งฉันรู้ว่ามีตัวอย่างมากมายฉันแค่มองหาตัวอย่างพร้อมคำอธิบายว่าเกิดอะไรขึ้นกันแน่และเหตุใดจึงเป็นเช่นนั้น

หากมีใครรู้เกี่ยวกับหนังสือ Android ที่ดีเกี่ยวกับเรื่องนี้โปรดแจ้งให้เราทราบ

ขอขอบคุณอีกครั้งสำหรับความช่วยเหลือ @terrance นี่คือรหัสที่ฉันอธิบายไว้ด้านล่าง

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

บางทีคุณอาจโพสต์หนึ่งในตัวอย่างที่คุณไม่สามารถทำงานได้? คุณจะได้เรียนรู้ว่าชิ้นงานเข้ากันได้อย่างไร
fredw

คำตอบ:


157

ในคำตอบนี้ฉันกำลังใช้ตัวอย่างเช่นโพสต์โดยจัสติน Grammens

เกี่ยวกับ JSON

JSON ย่อมาจาก JavaScript Object Notation ใน JavaScript คุณสมบัติสามารถอ้างอิงได้ทั้งสองอย่างนี้และเช่นนี้object1.name object['name'];ตัวอย่างจากบทความใช้ JSON นี้เล็กน้อย


วัตถุชิ้นส่วนแฟนที่มีอีเมลเป็นคีย์และ foo@bar.com เป็นค่า

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

ดังนั้นเทียบเท่าวัตถุที่จะเป็นหรือfan.email; ทั้งสองฝ่ายจะมีค่าเดียวกันของfan['email'];'foo@bar.com'

เกี่ยวกับคำขอ HttpClient

ต่อไปนี้คือสิ่งที่ผู้เขียนใช้ในการทำHttpClient ขอ ฉันไม่ได้อ้างว่าเป็นผู้เชี่ยวชาญ แต่อย่างใดดังนั้นหากใครมีวิธีที่ดีกว่าในการใช้คำศัพท์บางคำก็อย่าลังเล

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

แผนที่

หากคุณยังไม่คุ้นเคยกับMapโครงสร้างข้อมูลโปรดดูที่อ้างอิง Java แผนที่ ในระยะสั้นแผนที่ก็คล้ายกับพจนานุกรมหรือแฮช

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

โปรดอย่าลังเลที่จะแสดงความคิดเห็นเกี่ยวกับคำถามใด ๆ ที่เกิดขึ้นเกี่ยวกับโพสต์นี้หรือหากฉันยังไม่ได้ทำอะไรให้ชัดเจนหรือหากฉันยังไม่ได้สัมผัสกับสิ่งที่คุณยังสับสน ... ฯลฯ อะไรก็ตามที่ปรากฏในหัวของคุณจริงๆ

(ฉันจะลบออกถ้า Justin Grammens ไม่อนุมัติ แต่ถ้าไม่เป็นเช่นนั้นขอบคุณ Justin ที่ใจเย็นกับมัน)

ปรับปรุง

ฉันยินดีที่จะได้รับความคิดเห็นเกี่ยวกับวิธีใช้รหัสและตระหนักว่ามีข้อผิดพลาดในประเภทการส่งคืน ลายเซ็นเมธอดถูกตั้งค่าให้ส่งคืนสตริง แต่ในกรณีนี้จะไม่ส่งคืนอะไรเลย ฉันเปลี่ยนลายเซ็นเป็น HttpResponse และจะแนะนำคุณไปยังลิงก์นี้ในการรับเนื้อหาตอบสนองของ HttpResponse ตัวแปรพา ธ คือ url และฉันอัปเดตเพื่อแก้ไขข้อผิดพลาดในโค้ด


ขอบคุณ @Terrance ดังนั้นในคลาสอื่นเขาจึงสร้างแผนที่ที่มีคีย์และค่าต่างกันซึ่งจะเปลี่ยนเป็น JSONObjects ในภายหลัง ฉันลองใช้สิ่งที่คล้ายกัน แต่ฉันไม่มีประสบการณ์กับแผนที่เช่นกันฉันจะเพิ่มโค้ดสำหรับสิ่งที่ฉันพยายามใช้กับโพสต์ต้นฉบับของฉัน คำอธิบายของคุณเกี่ยวกับสิ่งที่เกิดขึ้นตั้งแต่นั้นมาและฉันประสบความสำเร็จในการทำให้มันใช้งานได้โดยการสร้าง JSONObjects ด้วยชื่อและค่าที่เข้ารหัส ขอบคุณ!

Woot ดีใจที่ฉันช่วยได้
Terrance

จัสตินบอกว่าเขาอนุมัติ เขาน่าจะมีตัวแทนเพียงพอที่จะมาและแสดงความคิดเห็นด้วยตัวเองในตอนนี้
Abizern

ฉันต้องการใช้รหัสนี้ ฉันจะไปเกี่ยวกับเรื่องนี้ได้อย่างไร? โปรดระบุตัวแปรเส้นทางคืออะไรและสิ่งที่ต้องส่งคืนเพื่อให้ฉันสามารถดึงข้อมูลได้ในตอนท้าย java
Prateek

3
ไม่มีเหตุผลสำหรับgetJsonObjectFromMap(): JSONObject มีตัวสร้างที่ใช้Map: developer.android.com/reference/org/json/…
pr1001

41

นี่คือทางเลือกอื่นสำหรับคำตอบของ @ Terrance คุณสามารถทำ Conversion จากภายนอกได้อย่างง่ายดาย ห้องสมุด Gsonทำงานที่ยอดเยี่ยมแปลงโครงสร้างข้อมูลต่างๆเป็น JSON และรอบวิธีอื่น ๆ

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

ที่คล้ายกันสามารถทำได้โดยใช้Jacksonแทน Gson ฉันขอแนะนำให้ดูที่ชุดติดตั้งเพิ่มเติมซึ่งซ่อนรหัสต้นแบบนี้ไว้มากมายสำหรับคุณ สำหรับนักพัฒนาที่มีประสบการณ์มากกว่าผมขอแนะนำให้พยายามออกRxAndroid


แอปของฉันกำลังส่งข้อมูลผ่านวิธี HttpPut เมื่อเซิร์ฟเวอร์ได้รับคำขอมันจะตอบกลับเป็นข้อมูล json ฉันไม่ทราบวิธีรับข้อมูลจาก json โปรดบอกฉัน. รหัส .
kongkea

@kongkea กรุณามีลักษณะเป็นที่ห้องสมุด GSON สามารถแยกวิเคราะห์ไฟล์ JSON ลงในวัตถุ Java
JJD

@JJD จนถึงตอนนี้สิ่งที่คุณแนะนำคือการส่งข้อมูลไปยังเซิร์ฟเวอร์ระยะไกลและคำอธิบายที่ดี แต่ต้องการทราบวิธีแยกวิเคราะห์วัตถุ JSON โดยใช้โปรโตคอล HTTP คุณสามารถอธิบายคำตอบของคุณอย่างละเอียดด้วยการแยกวิเคราะห์ JSON ด้วย จะเป็นประโยชน์มากสำหรับทุกคนที่เพิ่งเข้ามาใหม่
AndroidDev

@AndroidDev กรุณาเปิดคำถามใหม่เนื่องจากคำถามนี้เกี่ยวกับการส่งข้อมูลจากไคลเอนต์ไปยังเซิร์ฟเวอร์ อย่าลังเลที่จะวางลิงค์ที่นี่
JJD

@JJD คุณกำลังเรียกวิธีนามธรรมexecute()และล้มเหลวแน่นอน
Konstantin Konopko

33

ผมขอแนะนำให้ใช้นี้แทนHttpURLConnection HttpGetตามที่HttpGetเลิกใช้แล้วใน Android API ระดับ 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

รหัสมากเกินไปสำหรับงานนี้ให้ชำระเงินไลบรารีนี้https://github.com/kodart/Httpzoid Is ใช้ GSON ภายในและมี API ที่ทำงานกับอ็อบเจ็กต์ รายละเอียด JSON ทั้งหมดถูกซ่อนไว้

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

ทางออกที่ยอดเยี่ยมน่าเสียดายที่ปลั๊กอินนี้ขาดการสนับสนุน gradle: /
electronix384128

3

มีสองวิธีในการสร้างการเชื่อมต่อ HHTP และดึงข้อมูลจากบริการเว็บ RESTFULL ล่าสุดคือ GSON แต่ก่อนที่คุณจะดำเนินการต่อไปยัง GSON คุณต้องมีความคิดเกี่ยวกับวิธีดั้งเดิมที่สุดในการสร้างไคลเอนต์ HTTP และทำการสื่อสารข้อมูลกับเซิร์ฟเวอร์ระยะไกล ฉันได้กล่าวถึงทั้งสองวิธีในการส่งคำขอ POST & GET โดยใช้ 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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.