如何使用 OKHTTP 发布请求?

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

有人说:

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

现在我想使一个普通的职位与名称和密码参数的 URL。

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

231664 次浏览

You need to encode it yourself by escaping strings with URLEncoder and joining them with "=" and "&". Or you can use FormEncoder from Mimecraft which gives you a handy builder.

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

You should check tutorials on lynda.com. Here is an example of how to encode the parameters, make HTTP request and then parse response to json object.

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

You can make it like this:

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


}
});

This is one of the possible solutions to implementing an OKHTTP post request without a request body.

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

As per the docs, OkHttp version 3 replaced FormEncodingBuilder with FormBody and FormBody.Builder(), so the old examples won't work anymore.

Form and Multipart bodies are now modeled. We've replaced the opaque FormEncodingBuilder with the more powerful FormBody and FormBody.Builder combo.

Similarly we've upgraded MultipartBuilder into MultipartBody, MultipartBody.Part, and MultipartBody.Builder.

So if you're using OkHttp 3.x try the following example:

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

Here is my method to do post request first pass in method map and data like

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

 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;


}

The current accepted answer is out of date. Now if you want to create a post request and add parameters to it you should user MultipartBody.Builder as 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();
   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;
}
  1. Add the following to the build.gradle

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

  1. Create a new thread, in the new thread add the following code.
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();

To add okhttp as a dependency do as follows

  • right click on the app on android studio open "module settings"
  • "dependencies"-> "add library dependency" -> "com.squareup.okhttp3:okhttp:3.10.0" -> add -> ok..

now you have okhttp as a dependency

Now design a interface as below so we can have the callback to our activity once the network response received.

public interface NetworkCallback {


public void getResponse(String res);
}

I create a class named NetworkTask so i can use this class to handle all the network requests

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

now let me show how to get the callback to an activity

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

OkHttp POST request with token in header

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

If you want to post parameter in okhttp as body content which can be encrypted string with content-type as "application/x-www-form-urlencoded" you can first use URLEncoder to encode the data and then use :

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

you can add header according to your requirement.

As for Kotlin in 2022 (POST request) works:

       val client = OkHttpClient()
val formBody: RequestBody = MultipartBody.Builder()
.addFormDataPart("phone", editText1.text.toString())
.addFormDataPart("email", editText2.text.toString())
.build()
val request: Request = Request.Builder()
.url("https://hellokitty.com/users")
.post(formBody)
.build()


try {
// Do something with the response.
val response = client.newCall(request).enqueue(object : Callback {


override fun onFailure(call: Call, e: okio.IOException) {
print(e.message)
}


override fun onResponse(call: Call, response: Response) {
print(response.message)
print("XXX \n" + response.body)
}
})
editTextResponse.text = response.toString()


} catch (e: java.io.IOException) {
editTextResponse.text = e.toString()
e.printStackTrace()
}

Gradle:

implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.6")

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jaskierltd.blablaApp">


<uses-permission android:name="android.permission.INTERNET"/>
...