一、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); // 设置请求参数 Listparams = new ArrayList (); 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"); // 设置请求参数 Listparams = new ArrayList (); 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(); } }); } }