Як за допомогою OKHTTP зробити запит на публікацію?


91

Я прочитав кілька прикладів, які публікують jsons на сервері.

хтось каже:

OkHttp - це реалізація інтерфейсу HttpUrlConnection, наданого Java. Він забезпечує вхідний потік для написання вмісту і не знає (або не турбується) про те, якого формату цей вміст.

Тепер я хочу зробити звичайний допис на URL-адресу з параметрами імені та пароля.

Це означає, що мені потрібно самому закодувати пару імені та значення у потік?


Я написав відповідь на відповідне запитання Як додати параметри до API (http post) за допомогою бібліотеки okhttp в Android . Він використовує лише OkHttp.
Суфіан

Хоча позначена відповідь є правильною, вона працює лише з версіями до 3.0. Я додав відповідь про те, як це працює зараз :)
Mauker

Відповіді:


101

Поточна прийнята відповідь застаріла. Тепер, якщо ви хочете створити запит на публікацію та додати до нього параметри, вам слід скористатися користувачем MultipartBody.Builder, оскільки Mime Craft зараз застарілий .

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

Як надіслати цілі числа в тілі запиту?
Адріан Поттінгер,

Перетворити intв String@AqibBangash
Mauker

2
До цієї роботи з відповідями слід додати заголовок типу вмісту, наприклад: .addHeader("Content-Type", " application/x-www-form-urlencoded")
ruzenhack

114

Відповідно до документів , OkHttp версії 3 замінено FormEncodingBuilderна FormBodyта FormBody.Builder(), тому старі приклади більше не працюватимуть.

Форми та багаточастинні тіла тепер змодельовані. Ми замінили непрозорий FormEncodingBuilderна більш потужний FormBodyта FormBody.Builderкомбінований.

Точно так само ми оновили MultipartBuilderв MultipartBody, MultipartBody.Partі MultipartBody.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, або де завгодно, крім основної
теми

.add("message", "Your message")у addвиклику методу який аргумент із двох рядків? Я хочу передати лише вміст рядка тіла . Як?
Янос

1
Перший аргумент - це ключ, другий - значення.
Mauker

Я отримую нульову відповідь від дзвінка вищевказаним методом, тоді як отримую належну відповідь, коли роблю виклик із curl. Що може бути причиною?
Рамеш Парік,

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/... вважають, що це справді хороші ресурси.
user2219372

1
Це не працює на OkHttp 3.x. Щоб побачити, як це працює, перевірте мою відповідь :)
Mauker

Для тих, хто шукає параметри GET: Подивіться на HttpUrlклас (з бібліотеки OkHttp).
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 );

        }
    });

на сьогоднішній
день

4

Щоб додати okhttp як залежність, виконайте наступне

  • клацніть правою кнопкою миші на додатку на android studio відкрийте "налаштування модуля"
  • "залежності" -> "додати бібліотечну залежність" -> "com.squareup.okhttp3: okhttp: 3.10.0" -> додати -> добре ..

тепер у вас залежність 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-адреси"
Венкатеш,

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

Растрове зображення bitmap = null; if (selectedphoto! = null) {try {bitmap = ImageLoader.init (). from (selectedphoto) .requestSize (512, 512) .getBitmap (); } catch (FileNotFoundException e) {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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.