Come utilizzare OKHTTP per effettuare una richiesta di post?


93

Ho letto alcuni esempi che stanno postando jsons sul server.

qualcuno dice:

OkHttp è un'implementazione dell'interfaccia HttpUrlConnection fornita da Java. Fornisce un flusso di input per la scrittura di contenuto e non sa (o si preoccupa) del formato di quel contenuto.

Ora voglio fare un normale post all'URL con parametri di nome e password.

Significa che devo codificare da solo il nome e la coppia di valori nel flusso?


Ho scritto una risposta a una domanda correlata Come aggiungere parametri a api (post http) utilizzando la libreria okhttp in Android . Utilizza solo OkHttp.
Sufian

Sebbene la risposta contrassegnata sia corretta, funziona solo con le versioni precedenti alla 3.0. Ho aggiunto una risposta su come funziona ora :)
Mauker

Ecco un esempio completo di okhttp3 su come inviare una richiesta di post .
Sakib Sami

Risposte:


102

La risposta attualmente accettata non è aggiornata. Ora, se si desidera creare una richiesta di post e aggiungere parametri ad essa, è necessario utilizzare MultipartBody.Builder poiché Mime Craft ora è deprecato .

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
Credo che la domanda originale non avesse nulla a che fare con Mime Craft. Ed entrambe le vecchie risposte accettate, dato che la più votata rispondeva già come fare una richiesta POST con le versioni OKHttp 2.xe 3.x.
Mauker

Come inviare numeri interi nel corpo della richiesta?
Adrian Pottinger

Converti il intin un String@AqibBangash
Mauker

2
A questo lavoro di risposta dovresti aggiungere l'intestazione del tipo di contenuto come: .addHeader("Content-Type", " application/x-www-form-urlencoded")
ruzenhack

115

Come da documentazione , OkHttp versione 3 sostituita FormEncodingBuildercon FormBodye FormBody.Builder(), quindi i vecchi esempi non funzioneranno più.

I corpi forma e multiparte sono ora modellati. Abbiamo sostituito l'opaco FormEncodingBuildercon il più potente FormBodye FormBody.Buildercombo.

Allo stesso modo abbiamo aggiornato MultipartBuilderin MultipartBody, MultipartBody.Parte MultipartBody.Builder.

Quindi, se stai usando OkHttp 3.x, prova il seguente esempio:

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
abbiamo bisogno di implementare il codice sopra all'interno di AsyncTask?
OnePunchMan

3
All'interno di un AsyncTask, o IntentService, o ovunque tranne che nel thread principale :)
Mauker

.add("message", "Your message")nella addchiamata al metodo qual è l'argomento a due stringhe? Voglio passare solo il contenuto della stringa del corpo . Come?
János

1
Il primo argomento è la chiave, il secondo è il valore.
Mauker

Ottengo una risposta nulla da una chiamata con il metodo sopra, mentre ottengo una risposta corretta quando effettuo una chiamata da curl. Quale potrebbe essere il motivo?
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

Devi codificarlo da solo facendo l'escape delle stringhe con URLEncoder e unendole con "="e "&". Oppure puoi usare FormEncoder di Mimecraft che ti offre un pratico generatore.

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

1
grazie .come caricare un file con okhttp? stackoverflow.com/questions/23512547/… penso che sia davvero una buona libreria.
user2219372

1
Questo non funziona su OkHttp 3.x. Per vedere come funziona, controlla la mia risposta :)
Mauker

Per chi cerca i parametri GET: guarda la HttpUrlclasse (dalla libreria OkHttp).
Mauker

15

Puoi farlo in questo modo:

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

        }
    });

deprecato ormai
inxoy

4

Per aggiungere okhttp come dipendenza, procedi come segue

  • fai clic con il pulsante destro del mouse sull'app su Android Studio apri "impostazioni modulo"
  • "dipendenze" -> "aggiungi dipendenza libreria" -> "com.squareup.okhttp3: okhttp: 3.10.0" -> aggiungi -> ok ..

ora hai okhttp come dipendenza

Ora progetta un'interfaccia come di seguito in modo da poter richiamare la nostra attività una volta ricevuta la risposta della rete.

public interface NetworkCallback {

    public void getResponse(String res);
}

Creo una classe denominata NetworkTask in modo da poter utilizzare questa classe per gestire tutte le richieste di rete

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

ora lascia che ti mostri come richiamare un'attività

    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

POSTRichiesta OkHttp con token nell'intestazione

       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

Questa è una delle possibili soluzioni per implementare una richiesta post OKHTTP senza un corpo di richiesta.

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

Il codice sopra funziona bene ma voglio con requestbody. Ho provato alcuni esempi ma non funzionava visualizzando l'errore: "Non hai il permesso di accedere a questo URL"
Venkatesh

2

Dovresti controllare i tutorial su lynda.com . Di seguito è riportato un esempio di come codificare i parametri, effettuare una richiesta HTTP e quindi analizzare la risposta all'oggetto 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 (selectedphoto! = null) {try {bitmap = ImageLoader.init (). from (selectedphoto) .requestSize (512, 512) .getBitmap (); } catch (FileNotFoundException e) {e.printStackTrace (); } encodeimg = ImageBase64.encode (bitmap); }
Utsav Kundu

1

Ecco il mio metodo per eseguire la prima richiesta di post nella mappa del metodo e dati come

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. Aggiungi quanto segue al file build.gradle

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

  1. Crea un nuovo thread, nel nuovo thread aggiungi il seguente codice.
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
Perché c'è così tanto codice per una cosa così semplice? Spiega per favore.
james.garriss
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.