จะใช้ OKHTTP เพื่อขอโพสต์ได้อย่างไร?


93

ฉันอ่านตัวอย่างที่โพสต์ jsons ไปยังเซิร์ฟเวอร์

บางคนพูดว่า:

OkHttp เป็นการใช้งานอินเตอร์เฟส HttpUrlConnection ที่จัดเตรียมโดย Java มีอินพุตสตรีมสำหรับการเขียนเนื้อหาและไม่ทราบ (หรือสนใจ) ว่าเนื้อหานั้นเป็นรูปแบบใด

ตอนนี้ฉันต้องการโพสต์ปกติไปยัง URL ด้วยพารามิเตอร์ชื่อและรหัสผ่าน

หมายความว่าฉันต้องเข้ารหัสชื่อและคู่ค่าลงในสตรีมด้วยตัวเอง?


ผมเขียนคำตอบของคำถามที่เกี่ยวข้องวิธีการเพิ่มพารามิเตอร์ให้กับ API (http โพสต์) การใช้ห้องสมุด okhttp ใน Android ใช้ OkHttp เท่านั้น
Sufian

แม้ว่าคำตอบที่ทำเครื่องหมายไว้จะถูกต้อง แต่ก็ใช้ได้กับเวอร์ชันก่อนหน้า 3.0 เท่านั้น ฉันได้เพิ่มคำตอบว่ามันทำงานอย่างไร :)
Mauker

นี่เป็นตัวอย่างที่สมบูรณ์แบบของ okhttp3 ในวิธีการที่จะส่งคำขอการโพสต์
Sakib Sami

คำตอบ:


102

คำตอบที่ยอมรับในปัจจุบันล้าสมัย ตอนนี้ถ้าคุณต้องการที่จะสร้างการร้องขอการโพสต์และเพิ่มพารามิเตอร์ให้กับมันคุณควร MultipartBody.Builder ใช้เป็นMime หัตถกรรมตอนนี้จะเลิก

RequestBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("somParam", "someValue")
        .build();

Request request = new Request.Builder()
        .url(BASE_URL + route)
        .post(requestBody)
        .build();

5
ฉันเชื่อว่าคำถามเดิมไม่มีส่วนเกี่ยวข้องกับ Mime Craft และทั้งสองคำตอบที่ได้รับการยอมรับซึ่งเป็นคำตอบที่ได้รับการโหวตมากที่สุดได้ตอบวิธีสร้างคำขอ POST ด้วย OKHttp เวอร์ชัน 2.x และ 3.x
Mauker

จะส่งจำนวนเต็มในคำขอ Body ได้อย่างไร
Adrian Pottinger

แปลงร่างintเป็นString@AqibBangash
Mauker

2
สำหรับคำตอบนี้คุณควรเพิ่มส่วนหัวประเภทเนื้อหาเช่น .addHeader("Content-Type", " application/x-www-form-urlencoded")
ruzenhack

115

ตามเอกสาร OkHttp เวอร์ชัน 3 ถูกแทนที่FormEncodingBuilderด้วยFormBodyและFormBody.Builder()ดังนั้นตัวอย่างเก่าจะไม่ทำงานอีกต่อไป

ตอนนี้ฟอร์มและเนื้อความหลายส่วนได้รับการสร้างแบบจำลองแล้ว เราได้แทนที่ทึบแสง FormEncodingBuilderที่มีประสิทธิภาพมากขึ้นFormBodyและ FormBody.Builderคำสั่งผสม

ในทำนองเดียวกันเราได้อัพเกรดMultipartBuilderเข้า MultipartBody, และMultipartBody.PartMultipartBody.Builder

ดังนั้นหากคุณใช้ OkHttp 3.x ลองทำตามตัวอย่างต่อไปนี้:

OkHttpClient client = new OkHttpClient();

RequestBody formBody = new FormBody.Builder()
        .add("message", "Your message")
        .build();
Request request = new Request.Builder()
        .url("http://www.foo.bar/index.php")
        .post(formBody)
        .build();

try {
    Response response = client.newCall(request).execute();

    // Do something with the response.
} catch (IOException e) {
    e.printStackTrace();
}

1
เราจำเป็นต้องติดตั้งโค้ดข้างต้นใน AsyncTask หรือไม่?
OnePunchMan

3
ภายในAsyncTaskหรือIntentServiceหรือที่ใดก็ได้ยกเว้นในเธรดหลัก :)
Mauker

.add("message", "Your message")ในaddเมธอดเรียกอาร์กิวเมนต์สองสตริงคืออะไร? ฉันต้องการส่งผ่านเฉพาะเนื้อหา Body String อย่างไร?
János

1
อาร์กิวเมนต์แรกเป็นกุญแจสำคัญส่วนที่สองคือค่า
Mauker

ฉันได้รับการตอบสนองเป็นโมฆะจากการโทรด้วยวิธีการข้างต้นในขณะที่ได้รับคำตอบที่เหมาะสมเมื่อฉันโทรออกจาก curl อะไรคือสาเหตุ?
Ramesh Pareek

37
private final OkHttpClient client = new OkHttpClient();

  public void run() throws Exception {
    RequestBody formBody = new FormEncodingBuilder()
        .add("search", "Jurassic Park")
        .build();
    Request request = new Request.Builder()
        .url("https://en.wikipedia.org/w/index.php")
        .post(formBody)
        .build();

    Response response = client.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

    System.out.println(response.body().string());
  }

19

คุณจำเป็นต้องเข้ารหัสด้วยตัวคุณเองโดยการหลบหนีสตริงกับURLEncoderและเข้าร่วมกับพวกเขาและ"=" "&"หรือคุณสามารถใช้FormEncoderจากMimecraftซึ่งช่วยให้คุณมีเครื่องมือสร้างที่สะดวก

FormEncoding fe = new FormEncoding.Builder()
    .add("name", "Lorem Ipsum")
    .add("occupation", "Filler Text")
    .build();

1
ขอบคุณวิธีการอัพโหลดไฟล์ด้วย okhttp? stackoverflow.com/questions/23512547/…คิดว่ามันเป็น libs ที่ดีจริงๆ
user2219372

1
สิ่งนี้ไม่ทำงานบน OkHttp 3.x หากต้องการดูวิธีการทำงานตรวจสอบคำตอบของฉัน :)
Mauker

สำหรับผู้ที่มองหาพารามิเตอร์ GET: ดูที่HttpUrlคลาส (จาก OkHttp lib)
Mauker

15

คุณสามารถทำให้เป็นดังนี้:

    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    RequestBody body = RequestBody.create(JSON, "{"jsonExample":"value"}");

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            .url(url)
            .post(body)
            .addHeader("Authorization", "header value") //Notice this request has header if you don't need to send a header just erase this part
            .build();

    Call call = client.newCall(request);

    call.enqueue(new Callback() {
        @Override
        public void onFailure(Request request, IOException e) {

            Log.e("HttpService", "onFailure() Request was: " + request);

            e.printStackTrace();
        }

        @Override
        public void onResponse(Response r) throws IOException {

            response = r.body().string();

            Log.e("response ", "onResponse(): " + response );

        }
    });

เลิกใช้แล้ว
inxoy

4

ในการเพิ่ม okhttp เป็นการอ้างอิงให้ทำดังนี้

  • คลิกขวาที่แอปบน android studio เปิด "การตั้งค่าโมดูล"
  • "dependencies" -> "add library dependency" -> "com.squareup.okhttp3: okhttp: 3.10.0" -> add -> ok ..

ตอนนี้คุณมี okhttp เป็นที่พึ่งพา

ตอนนี้ออกแบบอินเทอร์เฟซดังต่อไปนี้เพื่อให้เราสามารถโทรกลับไปที่กิจกรรมของเราได้เมื่อได้รับการตอบกลับเครือข่าย

public interface NetworkCallback {

    public void getResponse(String res);
}

ฉันสร้างคลาสชื่อ NetworkTask เพื่อให้ฉันสามารถใช้คลาสนี้เพื่อจัดการกับคำขอเครือข่ายทั้งหมด

    public class NetworkTask extends AsyncTask<String , String, String>{

    public NetworkCallback instance;
    public String url ;
    public String json;
    public int task ;
    OkHttpClient client = new OkHttpClient();
    public static final MediaType JSON
            = MediaType.parse("application/json; charset=utf-8");

    public NetworkTask(){

    }

    public NetworkTask(NetworkCallback ins, String url, String json, int task){
        this.instance = ins;
        this.url = url;
        this.json = json;
        this.task = task;
    }


    public String doGetRequest() throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .build();

        Response response = client.newCall(request).execute();
        return response.body().string();
    }

    public String doPostRequest() throws IOException {
        RequestBody body = RequestBody.create(JSON, json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Response response = client.newCall(request).execute();
        return response.body().string();
    }

    @Override
    protected String doInBackground(String[] params) {
        try {
            String response = "";
            switch(task){
                case 1 :
                    response = doGetRequest();
                    break;
                case 2:
                    response = doPostRequest();
                    break;

            }
            return response;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        instance.getResponse(s);
    }
}

ตอนนี้ให้ฉันแสดงวิธีเรียกกลับไปที่กิจกรรม

    public class MainActivity extends AppCompatActivity implements NetworkCallback{
    String postUrl = "http://your-post-url-goes-here";
    String getUrl = "http://your-get-url-goes-here";
    Button doGetRq;
    Button doPostRq;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.button);

        doGetRq = findViewById(R.id.button2);
    doPostRq = findViewById(R.id.button1);

        doPostRq.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MainActivity.this.sendPostRq();
            }
        });

        doGetRq.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MainActivity.this.sendGetRq();
            }
        });
    }

    public void sendPostRq(){
        JSONObject jo = new JSONObject();
        try {
            jo.put("email", "yourmail");
            jo.put("password","password");

        } catch (JSONException e) {
            e.printStackTrace();
        }
    // 2 because post rq is for the case 2
        NetworkTask t = new NetworkTask(this, postUrl,  jo.toString(), 2);
        t.execute(postUrl);
    }

    public void sendGetRq(){

    // 1 because get rq is for the case 1
        NetworkTask t = new NetworkTask(this, getUrl,  jo.toString(), 1);
        t.execute(getUrl);
    }

    @Override
    public void getResponse(String res) {
    // here is the response from NetworkTask class
    System.out.println(res)
    }
}

4

POSTคำขอOkHttp พร้อมโทเค็นในส่วนหัว

       RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("search", "a")
            .addFormDataPart("model", "1")
            .addFormDataPart("in", "1")
            .addFormDataPart("id", "1")
            .build();
    OkHttpClient client = new OkHttpClient();
    okhttp3.Request request = new okhttp3.Request.Builder()
            .url("https://somedomain.com/api")
            .post(requestBody)
            .addHeader("token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIkMnkkMTAkZzZrLkwySlFCZlBmN1RTb3g3bmNpTzltcVwvemRVN2JtVC42SXN0SFZtbzZHNlFNSkZRWWRlIiwic3ViIjo0NSwiaWF0IjoxNTUwODk4NDc0LCJleHAiOjE1NTM0OTA0NzR9.tefIaPzefLftE7q0yKI8O87XXATwowEUk_XkAOOQzfw")
            .addHeader("cache-control", "no-cache")
            .addHeader("Postman-Token", "7e231ef9-5236-40d1-a28f-e5986f936877")
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, okhttp3.Response response) throws IOException {
            if (response.isSuccessful()) {
                final String myResponse = response.body().string();

                MainActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d("response", myResponse);
                        progress.hide();
                    }
                });
            }
        }
    });

3

นี่เป็นหนึ่งในวิธีแก้ไขที่เป็นไปได้ในการดำเนินการตามคำขอโพสต์ OKHTTP โดยไม่มีเนื้อหาคำขอ

RequestBody reqbody = RequestBody.create(null, new byte[0]);  
Request.Builder formBody = new Request.Builder().url(url).method("POST",reqbody).header("Content-Length", "0");
clientOk.newCall(formBody.build()).enqueue(OkHttpCallBack());

โค้ดด้านบนใช้งานได้ดี แต่ฉันต้องการกับ requestbody ฉันลองใช้บางตัวอย่าง แต่ไม่ทำงานแสดงข้อผิดพลาด: "คุณไม่มีสิทธิ์เข้าถึง URL นี้"
Venkatesh

2

คุณควรตรวจสอบแบบฝึกหัดในlynda.com นี่คือตัวอย่างของวิธีการเข้ารหัสพารามิเตอร์สร้างคำขอ HTTP จากนั้นแยกวิเคราะห์การตอบสนองไปยังวัตถุ json

public JSONObject getJSONFromUrl(String str_url, List<NameValuePair> params) {      
        String reply_str = null;
        BufferedReader reader = null;

        try {
            URL url = new URL(str_url);
            OkHttpClient client = new OkHttpClient();
            HttpURLConnection con = client.open(url);                           
            con.setDoOutput(true);
            OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
            writer.write(getEncodedParams(params));
            writer.flush();     
            StringBuilder sb = new StringBuilder();
            reader = new BufferedReader(new InputStreamReader(con.getInputStream()));           
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }           
            reply_str = sb.toString();              
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }

        // try parse the string to a JSON object. There are better ways to parse data.
        try {
            jObj = new JSONObject(reply_str);            
        } catch (JSONException e) {   
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }     
      return jObj;
    }

    //in this case it's NameValuePair, but you can use any container
    public String getEncodedParams(List<NameValuePair> params) {
        StringBuilder sb = new StringBuilder();
        for (NameValuePair nvp : params) {
            String key = nvp.getName();
            String param_value = nvp.getValue();
            String value = null;
            try {
                value = URLEncoder.encode(param_value, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(key + "=" + value);
        }
        return sb.toString();
    }

2
   protected Void doInBackground(String... movieIds) {
                for (; count <= 1; count++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                Resources res = getResources();
                String web_link = res.getString(R.string.website);

                OkHttpClient client = new OkHttpClient();

                RequestBody formBody = new FormBody.Builder()
                        .add("name", name)
                        .add("bsname", bsname)
                        .add("email", email)
                        .add("phone", phone)
                        .add("whatsapp", wapp)
                        .add("location", location)
                        .add("country", country)
                        .add("state", state)
                        .add("city", city)
                        .add("zip", zip)
                        .add("fb", fb)
                        .add("tw", tw)
                        .add("in", in)
                        .add("age", age)
                        .add("gender", gender)
                        .add("image", encodeimg)
                        .add("uid", user_id)
                        .build();
                Request request = new Request.Builder()
                        .url(web_link+"edit_profile.php")
                        .post(formBody)
                        .build();

                try {
                    Response response = client.newCall(request).execute();

                    JSONArray array = new JSONArray(response.body().string());
                    JSONObject object = array.getJSONObject(0);

                    hashMap.put("msg",object.getString("msgtype"));
                    hashMap.put("msg",object.getString("msg"));
                    // Do something with the response.
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }



                return null;
            }

บิตแมปบิตแมป = null; ถ้า (selectedphoto! = null) {ลอง {bitmap = ImageLoader.init () จาก (selectedphoto) .requestSize (512, 512) .getBitmap (); } จับ (FileNotFoundException จ) {e.printStackTrace (); } encodeimg = ImageBase64.encode (บิตแมป); }
Utsav Kundu

1

นี่คือวิธีการของฉันในการโพสต์คำขอก่อนส่งในเมธอดเมธอดและข้อมูลเช่น

HashMap<String, String> param = new HashMap<String, String>();

param.put("Name", name);
param.put("Email", email);
param.put("Password", password);
param.put("Img_Name", "");

final JSONObject result = doPostRequest(map,Url);

public static JSONObject doPostRequest(HashMap<String, String> data, String url) {

    try {
        RequestBody requestBody;
        MultipartBuilder mBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);

        if (data != null) {


            for (String key : data.keySet()) {
                String value = data.get(key);
                Utility.printLog("Key Values", key + "-----------------" + value);

                mBuilder.addFormDataPart(key, value);

            }
        } else {
            mBuilder.addFormDataPart("temp", "temp");
        }
        requestBody = mBuilder.build();


        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        OkHttpClient client = new OkHttpClient();
        Response response = client.newCall(request).execute();
        String responseBody = response.body().string();
        Utility.printLog("URL", url);
        Utility.printLog("Response", responseBody);
        return new JSONObject(responseBody);

    } catch (UnknownHostException | UnsupportedEncodingException e) {

        JSONObject jsonObject=new JSONObject();

        try {
            jsonObject.put("status","false");
            jsonObject.put("message",e.getLocalizedMessage());
        } catch (JSONException e1) {
            e1.printStackTrace();
        }
        Log.e(TAG, "Error: " + e.getLocalizedMessage());
    } catch (Exception e) {
        e.printStackTrace();
        JSONObject jsonObject=new JSONObject();

        try {
            jsonObject.put("status","false");
            jsonObject.put("message",e.getLocalizedMessage());
        } catch (JSONException e1) {
            e1.printStackTrace();
        }
        Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
    }
    return null;
}


1
  1. เพิ่มสิ่งต่อไปนี้ใน build.gradle

compile 'com.squareup.okhttp3:okhttp:3.7.0'

  1. สร้างเธรดใหม่ในเธรดใหม่เพิ่มรหัสต่อไปนี้
OkHttpClient client = new OkHttpClient();
MediaType MIMEType= MediaType.parse("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create (MIMEType,"{}");
Request request = new Request.Builder().url(url).post(requestBody).build();
Response response = client.newCall(request).execute();

-4
 public static JSONObject doPostRequestWithSingleFile(String url,HashMap<String, String> data, File file,String fileParam) {

        try {
            final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

            RequestBody requestBody;
            MultipartBuilder mBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);

            for (String key : data.keySet()) {
                String value = data.get(key);
                Utility.printLog("Key Values", key + "-----------------" + value);

                mBuilder.addFormDataPart(key, value);

            }
            if(file!=null) {
                Log.e("File Name", file.getName() + "===========");
                if (file.exists()) {
                    mBuilder.addFormDataPart(fileParam, file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file));
                }
            }
            requestBody = mBuilder.build();
            Request request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();

            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            String result=response.body().string();
            Utility.printLog("Response",result+"");
            return new JSONObject(result);

        } catch (UnknownHostException | UnsupportedEncodingException e) {
            Log.e(TAG, "Error: " + e.getLocalizedMessage());
            JSONObject jsonObject=new JSONObject();

            try {
                jsonObject.put("status","false");
                jsonObject.put("message",e.getLocalizedMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        } catch (Exception e) {
            Log.e(TAG, "Other Error: " + e.getMessage());
            JSONObject jsonObject=new JSONObject();

            try {
                jsonObject.put("status","false");
                jsonObject.put("message",e.getLocalizedMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        }
        return null;
    }
    public static JSONObject doGetRequest(HashMap<String, String> param,String url) {
        JSONObject result = null;
        String response;
        Set keys = param.keySet();

        int count = 0;
        for (Iterator i = keys.iterator(); i.hasNext(); ) {
            count++;
            String key = (String) i.next();
            String value = (String) param.get(key);
            if (count == param.size()) {
                Log.e("Key",key+"");
                Log.e("Value",value+"");
                url += key + "=" + URLEncoder.encode(value);

            } else {
                Log.e("Key",key+"");
                Log.e("Value",value+"");

                url += key + "=" + URLEncoder.encode(value) + "&";
            }

        }
/*
        try {
            url=  URLEncoder.encode(url, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }*/
        Log.e("URL", url);
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url(url)
                .build();
        Response responseClient = null;
        try {


            responseClient = client.newCall(request).execute();
            response = responseClient.body().string();
            result = new JSONObject(response);
            Log.e("response", response+"==============");
        } catch (Exception e) {
            JSONObject jsonObject=new JSONObject();

            try {
                jsonObject.put("status","false");
                jsonObject.put("message",e.getLocalizedMessage());
                return  jsonObject;
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }

        return result;

    }

1
เหตุใดจึงมีรหัสมากมายสำหรับสิ่งง่ายๆเช่นนี้? กรุณาอธิบาย.
james.garriss
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.