如何使用 OKHTTP 发出 post 请求?

Posted

技术标签:

【中文标题】如何使用 OKHTTP 发出 post 请求?【英文标题】:How to use OKHTTP to make a post request? 【发布时间】:2014-06-20 19:28:17 【问题描述】:

我阅读了一些将 json 发布到服务器的示例。

有人说:

OkHttp 是 HttpUrlConnection 接口的一个实现 由 Java 提供。它提供了一个用于写入内容的输入流和 不知道(或关心)内容是什么格式。

现在我想用名称和密码参数向 URL 发一个普通的帖子。

这意味着我需要自己将名称和值对编码到流中?

【问题讨论】:

我写了一个相关问题的答案How to add parameters to api (http post) using okhttp library in android。它只使用 OkHttp。 虽然标记的答案是正确的,但它只适用于 3.0 之前的版本。我已经添加了一个关于它现在如何工作的答案:) 这是how to send post request上的okhttp3的完整示例。 【参考方案1】:

根据the docs,OkHttp 版本 3 将 FormEncodingBuilder 替换为 FormBodyFormBody.Builder(),因此旧示例不再适用。

现在对窗体和多部分实体进行了建模。我们已经替换了不透明的 FormEncodingBuilder 与更强大的FormBodyFormBody.Builder组合。

同样,我们将MultipartBuilder 升级为 MultipartBodyMultipartBody.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("https://www.example.com/index.php")
        .post(formBody)
        .build();

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

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

【讨论】:

我们需要在AsyncTask里面实现上面的代码吗? AsyncTask,或IntentService,或除主线程之外的任何地方:) .add("message", "Your message")add 方法调用中的两个字符串参数是什么?我只想传递一个 body 字符串内容。怎么样? 第一个参数是键,第二个是值。 我通过上述方法从调用中得到空响应,而当我从 curl 调用时得到正确响应。可能是什么原因?【参考方案2】:

当前接受的答案已过期。现在,如果您想创建一个发布请求并向其添加参数,您应该使用 MultipartBody.Builder 作为Mime Craft now is deprecated。

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

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

【讨论】:

我相信最初的问题与 Mime Craft 几乎没有关系。两个旧的公认答案,因为投票最多的答案已经回答了如何使用 OKHttp 版本 2.x 和 3.x 发出 POST 请求。 如何在请求正文中发送整数? int 转换为String @AqibBangash 对于这个答案工作,您应该添加内容类型标题,如:.addHeader("Content-Type", " application/x-www-form-urlencoded")【参考方案3】:
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());
  

【讨论】:

【参考方案4】:

您需要通过使用URLEncoder 转义字符串并使用"=""&" 加入它们来自己对其进行编码。或者您可以使用Mimecraft 中的FormEncoder,它为您提供了一个方便的构建器。

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

【讨论】:

谢谢。如何使用 okhttp 上传文件?***.com/questions/23512547/… 认为这是一个非常好的库。 这不适用于 OkHttp 3.x。要了解它是如何工作的,请查看我的答案 :) 对于那些寻找 GET 参数的人:查看 HttpUrl 类(来自 OkHttp 库)。【参考方案5】:

你可以这样:

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

        
    );

【讨论】:

现在已弃用【参考方案6】:

OkHttp POST 请求头中带有令牌

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

【讨论】:

【参考方案7】:

要添加 okhttp 作为依赖项,请执行以下操作

在android studio上右键点击应用打开“模块设置” “依赖”->“添加库依赖”->“com.squareup.okhttp3:okhttp:3.10.0”->添加->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)
    

【讨论】:

【参考方案8】:

这是在没有请求正文的情况下实现 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”【参考方案9】:

您应该查看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();
    

【讨论】:

【参考方案10】:
   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(位图); 【参考方案11】:

这是我的发布请求方法 首先传入方法映射和数据,如

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;


【讨论】:

【参考方案12】:
    将以下内容添加到 build.gradle

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

    创建一个新线程,在新线程中添加如下代码。
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();

【讨论】:

【参考方案13】:

如果您想在 okhttp 中发布参数作为正文内容,可以使用 content-type 为“application/x-www-form-urlencoded”的加密字符串,您可以先使用 URLEncoder 对数据进行编码,然后使用:

final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("application/x-www-form-urlencoded");

okhttp3.Request request = new okhttp3.Request.Builder()
    .url(urlOfServer)
    .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, yourBodyDataToPostOnserver))
    .build();

您可以根据需要添加标题。

【讨论】:

【参考方案14】:
 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;

    

【讨论】:

为什么这么简单的事情有这么多代码?请解释一下。

以上是关于如何使用 OKHTTP 发出 post 请求?的主要内容,如果未能解决你的问题,请参考以下文章

OkHttp初探:如何使用OkHttp进行Get或Post请求?Kotlin版本。

如何使用“Content-type:application/x-www-form-urlencoded”发出 Okhttp 请求?

与改造一起使用时,OkHttp 不会重定向 POST 请求

OkHttp 如何提交 POST 请求?

OkHttp如何记录请求正文

OkHttp 2.0 响应(POST 请求)正文字符串为空字符串