Làm thế nào để sử dụng OKHTTP để thực hiện một yêu cầu đăng bài?


91

Tôi đọc một số ví dụ đang đăng jsons lên máy chủ.

Ai đó nói :

OkHttp là một triển khai của giao diện HttpUrlConnection do Java cung cấp. Nó cung cấp một luồng đầu vào để viết nội dung và không biết (hoặc quan tâm) về định dạng nội dung đó.

Bây giờ tôi muốn tạo một bài đăng bình thường đến URL với các thông số tên và mật khẩu.

Nó có nghĩa là tôi cần phải tự mình mã hóa cặp tên và giá trị thành luồng?


Tôi đã viết câu trả lời cho câu hỏi liên quan Cách thêm tham số vào api (bài đăng http) bằng thư viện okhttp trong Android . Nó chỉ sử dụng OkHttp.
Sufian,

Mặc dù câu trả lời được đánh dấu là đúng, nhưng nó chỉ hoạt động với các phiên bản trước 3.0. Tôi đã thêm câu trả lời về cách nó hoạt động ngay bây giờ :)
Mauker

Đây là một ví dụ đầy đủ của okhttp3 về cách gửi yêu cầu bài đăng .
Sakib Sami

Câu trả lời:


101

Câu trả lời được chấp nhận hiện tại đã lỗi thời. Bây giờ nếu bạn muốn tạo một yêu cầu bài đăng và thêm các thông số vào nó, bạn nên sử dụng MultipartBody.Builder như Mime Craft hiện không được dùng nữa .

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
Tôi tin rằng câu hỏi ban đầu chẳng liên quan gì đến Mime Craft. Và cả câu trả lời cũ được chấp nhận, vì câu được bình chọn nhiều nhất đã trả lời cách thực hiện yêu cầu ĐĂNG với OKHttp phiên bản 2.x và 3.x.
Mauker

Làm thế nào để gửi Số nguyên trong phần thân yêu cầu?
Adrian Pottinger

Chuyển đổi intđến một String@AqibBangash
Mauker

2
Để làm việc câu trả lời này, bạn nên thêm tiêu đề content-type như: .addHeader("Content-Type", " application/x-www-form-urlencoded")
ruzenhack

114

Theo tài liệu , OkHttp phiên bản 3 đã thay thế FormEncodingBuilderbằng FormBodyFormBody.Builder(), vì vậy các ví dụ cũ sẽ không hoạt động nữa.

Các phần thân của Form và Multipart hiện đã được lập mô hình. Chúng tôi đã thay thế sự mờ đục FormEncodingBuilderbằng sự kết hợp FormBodyvà mạnh mẽ hơn FormBody.Builder.

Tương tự như vậy, chúng tôi đã nâng cấp MultipartBuilderthành MultipartBody, MultipartBody.PartMultipartBody.Builder.

Vì vậy, nếu bạn đang sử dụng OkHttp 3.x, hãy thử ví dụ sau:

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
chúng ta có cần triển khai đoạn mã trên bên trong AsyncTask không?
OnePunchMan

3
Bên trong một AsyncTask, hoặc IntentService, hoặc bất cứ nơi nào ngoại trừ trong chuỗi chính :)
Mauker

.add("message", "Your message")trong addphương thức gọi đối số hai chuỗi là gì? Tôi muốn vượt qua chỉ là một cơ thể nội dung chuỗi. Làm sao?
János

1
Đối số đầu tiên là khóa, đối số thứ hai là giá trị.
Mauker

Tôi nhận được phản hồi rỗng từ một cuộc gọi theo phương thức trên, trong khi nhận được phản hồi thích hợp khi tôi thực hiện cuộc gọi từ curl. Điều gì có thể là lý do?
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

Bạn cần tự mã hóa nó bằng cách thoát các chuỗi bằng URLEncoder và nối chúng với "=""&". Hoặc bạn có thể sử dụng FormEncoder từ Mimecraft cung cấp cho bạn một trình xây dựng tiện dụng.

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

1
cảm ơn. Làm thế nào để tải lên một tệp với okhttp? stackoverflow.com/questions/23512547/… nghĩ rằng đó là một libs thực sự tốt.
user2219372

1
Điều này không hoạt động trên OkHttp 3.x. Để xem nó hoạt động như thế nào, hãy kiểm tra câu trả lời của tôi :)
Mauker

Đối với những người đang tìm kiếm thông số GET: Nhìn vào HttpUrllớp (Từ lib OkHttp).
Mauker

15

Bạn có thể làm cho nó như thế này:

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

        }
    });

bây giờ không được dùng nữa
inxoy

4

Để thêm okhttp làm phụ thuộc, hãy làm như sau

  • nhấp chuột phải vào ứng dụng trên android studio mở "cài đặt mô-đun"
  • "phụ thuộc" -> "thêm phụ thuộc thư viện" -> "com.squareup.okhttp3: okhttp: 3.10.0" -> thêm -> ok ..

bây giờ bạn có okhttp như một phụ thuộc

Bây giờ, hãy thiết kế một giao diện như bên dưới để chúng ta có thể gọi lại hoạt động của mình sau khi nhận được phản hồi mạng.

public interface NetworkCallback {

    public void getResponse(String res);
}

Tôi tạo một lớp có tên NetworkTask để tôi có thể sử dụng lớp này để xử lý tất cả các yêu cầu mạng

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

bây giờ hãy để tôi chỉ cách gọi lại một hoạt động

    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

POSTYêu cầu OkHttp với mã thông báo trong tiêu đề

       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

Đây là một trong những giải pháp khả thi để thực hiện yêu cầu đăng OKHTTP mà không cần cơ quan yêu cầu.

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

Mã trên hoạt động tốt nhưng tôi muốn với người yêu cầu. Tôi đã thử một số ví dụ nhưng không hoạt động khi hiển thị lỗi: "Bạn không có quyền truy cập url này"
Venkatesh

2

Bạn nên xem hướng dẫn trên lynda.com . Đây là một ví dụ về cách mã hóa các tham số, thực hiện yêu cầu HTTP và sau đó phân tích cú pháp phản hồi cho đối tượng 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;
            }

Bitmap bitmap = null; if (selectphoto! = null) {try {bitmap = ImageLoader.init (). from (selectphoto) .requestSize (512, 512) .getBitmap (); } catch (FileNotFoundException e) {e.printStackTrace (); } encodeimg = ImageBase64.encode (bitmap); }
Utsav Kundu

1

Đây là phương pháp của tôi để thực hiện yêu cầu đăng lần đầu tiên trong bản đồ phương thức và dữ liệu như

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. Thêm phần sau vào build.gradle

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

  1. Tạo một chuỗi mới, trong chuỗi mới thêm đoạn mã sau.
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
Tại sao có quá nhiều mã cho một điều đơn giản như vậy? Vui lòng giải thích.
james.garriss
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.