一、HttpClient简介
HttpClient是Apache组织发布的开源HTTP客户端库,它支持多线程连接、连接池、SSL、Cookie等特性。Python、Java、C#、C++等多个语言都有HttpClient的实现,本文介绍的是在Android平台上使用HttpClient发送HTTP请求。
二、HttpClient使用流程
HttpClient的使用流程大致如下:
// 创建HttpClient对象,设置连接池和Cookie存储
HttpClient httpClient = new DefaultHttpClient();
httpClient.setConnPoolTimeout(30 * 1000); // 设置连接超时时间
httpClient.setSoTimeout(30 * 1000); // 设置读取超时时间
httpClient.setCookieStore(new BasicCookieStore()); // 设置Cookie存储
// 创建Http请求对象
HttpPost httpPost = new HttpPost(url);
// 设置请求参数
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", "test"));
params.add(new BasicNameValuePair("password", "123456"));
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
// 执行Http请求,获取响应对象
HttpResponse response = httpClient.execute(httpPost);
// 解析响应结果
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
上述代码通过创建HttpClient对象、创建Http请求对象、设置请求参数、执行Http请求、解析响应结果等步骤来发送HTTP请求。
三、发送GET请求
使用HttpClient发送GET请求也比较简单,只需要使用HttpGet对象替换HttpPost对象,并传入请求参数即可。
// 创建Http请求对象
HttpGet httpGet = new HttpGet(url + "?param=123");
// 执行Http请求,获取响应对象
HttpResponse response = httpClient.execute(httpGet);
// 解析响应结果
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
四、发送文件
使用HttpClient发送文件需要使用MultipartEntityBuilder对象,它可以添加文件参数、普通参数,可以设置字符编码,也可以设置进度监听器。
// 创建Http请求对象
HttpPost httpPost = new HttpPost(url);
// 创建MultipartEntityBuilder对象,设置字符编码和进度监听器
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
.setCharset(Charset.forName("UTF-8"))
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addPart("file", new FileBody(file, ContentType.DEFAULT_BINARY))
.addTextBody("param1", "value1", ContentType.create("text/plain", Charset.forName("UTF-8")))
.addTextBody("param2", "value2", ContentType.create("text/plain", Charset.forName("UTF-8")))
.setBoundary("----WebKitFormBoundary7MA4YWxkTrZu0gW");
// 设置请求参数
httpPost.setEntity(builder.build());
// 执行Http请求,获取响应对象
HttpResponse response = httpClient.execute(httpPost);
// 解析响应结果
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
五、发送JSON数据
使用HttpClient发送JSON数据需要使用StringEntity对象,它可以设置字符编码和Content-Type。
// 创建Http请求对象
HttpPost httpPost = new HttpPost(url);
// 设置请求头和请求参数
httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
httpPost.setEntity(new StringEntity(jsonStr, "UTF-8"));
// 执行Http请求,获取响应对象
HttpResponse response = httpClient.execute(httpPost);
// 解析响应结果
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
六、完整示例代码
package com.example.httpclientdemo;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.NameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private TextView mResultTv;
private Button mGetBtn;
private Button mPostBtn;
private Button mFileBtn;
private Button mJsonBtn;
private HttpClient mHttpClient;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
mResultTv.setText("GET请求结果:\n" + msg.obj);
break;
case 1:
mResultTv.setText("POST请求结果:\n" + msg.obj);
break;
case 2:
mResultTv.setText("文件上传请求结果:\n" + msg.obj);
break;
case 3:
mResultTv.setText("JSON请求结果:\n" + msg.obj);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mResultTv = (TextView) findViewById(R.id.result_tv);
mGetBtn = (Button) findViewById(R.id.get_btn);
mPostBtn = (Button) findViewById(R.id.post_btn);
mFileBtn = (Button) findViewById(R.id.file_btn);
mJsonBtn = (Button) findViewById(R.id.json_btn);
// 创建HttpClient对象
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
connectionManager.setMaxTotal(10);
connectionManager.setDefaultMaxPerRoute(3);
ConnManagerParams.setTimeout(connectionManager.getParams(), 10000);
mHttpClient = new DefaultHttpClient(connectionManager);
mGetBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 发送GET请求
new Thread(new Runnable() {
@Override
public void run() {
Message msg = Message.obtain();
try {
// 创建Http请求对象
HttpGet httpGet = new HttpGet("https://www.baidu.com");
// 执行Http请求,获取响应对象
HttpResponse response = mHttpClient.execute(httpGet);
// 解析响应结果
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
msg.what = 0;
msg.obj = result;
} catch (IOException e) {
e.printStackTrace();
msg.obj = e.getMessage();
} finally {
mHandler.sendMessage(msg);
}
}
}).start();
}
});
mPostBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 发送POST请求
new Thread(new Runnable() {
@Override
public void run() {
Message msg = Message.obtain();
try {
// 创建Http请求对象
HttpPost httpPost = new HttpPost("https://www.baidu.com");
// 设置请求参数
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", "test"));
params.add(new BasicNameValuePair("password", "123456"));
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
// 执行Http请求,获取响应对象
HttpResponse response = mHttpClient.execute(httpPost);
// 解析响应结果
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
msg.what = 1;
msg.obj = result;
} catch (IOException e) {
e.printStackTrace();
msg.obj = e.getMessage();
} finally {
mHandler.sendMessage(msg);
}
}
}).start();
}
});
mFileBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 发送文件请求
new Thread(new Runnable() {
@Override
public void run() {
Message msg = Message.obtain();
try {
// 创建Http请求对象
HttpPost httpPost = new HttpPost("http://www.example.com/upload");
// 创建MultipartEntityBuilder对象,设置字符编码和进度监听器
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
.setCharset(Charset.forName("UTF-8"))
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addPart("file", new FileBody(new File("/sdcard/Download/test.jpg"), ContentType.DEFAULT_BINARY))
.addTextBody("name", "test", ContentType.create("text/plain", Charset.forName("UTF-8")))
.setBoundary("----WebKitFormBoundary7MA4YWxkTrZu0gW");
// 设置请求参数
httpPost.setEntity(builder.build());
// 执行Http请求,获取响应对象
HttpResponse response = mHttpClient.execute(httpPost);
// 解析响应结果
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
msg.what = 2;
msg.obj = result;
} catch (IOException e) {
e.printStackTrace();
msg.obj = e.getMessage();
} finally {
mHandler.sendMessage(msg);
}
}
}).start();
}
});
mJsonBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 发送JSON请求
new Thread(new Runnable() {
@Override
public void run() {
Message msg = Message.obtain();
try {
// 创建Http请求对象
HttpPost httpPost = new HttpPost("http://www.example.com/json");
// 设置请求头和请求参数
httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
String jsonStr = "{\"name\":\"test\",\"age\":18}";
httpPost.setEntity(new StringEntity(jsonStr, "UTF-8"));
// 执行Http请求,获取响应对象
HttpResponse response = mHttpClient.execute(httpPost);
// 解析响应结果
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
msg.what = 3;
msg.obj = result;
} catch (IOException e) {
e.printStackTrace();
msg.obj = e.getMessage();
} finally {
mHandler.sendMessage(msg);
}
}
}).start();
}
});
}
}