接上文HttpURLConnection
https://blog.csdn.net/nishigesb123/article/details/89328097
上文提到了,Android主要有三种形式实现网络编程,HttpURLConnection一种,Apache HTTP Client也是一种。
但是Android 6.0(api 23) 谷歌将Http Client相关类移除了,并且在官网API文档中也声明,不推荐使用HttpClient而推荐使用HttpURLConnection。
当然,也只是就安卓而言,其他领域或许还是会用到Apache HTTP Client的。
关于被弃用的原因,找到一篇翻译了当时官方声明的博文
https://blog.csdn.net/Jack_EUSong/article/details/50966020
谷歌支持HttpURLConnection原因有:
- 谷歌不愿意维护HTTPclient ,因为HTTPclient兼容性问题, 而支持HttpURLConnection
- HttpURLConnection API简便而且包小,对安卓很合适
- HttpURLConnection 对于提高速度和节省电池有帮助,同时谷歌也愿意在这方面花时间研究去更进一步的提高性能。
所以本文不对Apache HTTP Client做深究。
另外,为了完成本案例,提供一个测试办法
出处:https://blog.csdn.net/u011150924/article/details/52763443
关于Android 5.1版本后HttpClinet废止,继续使用HttpClinet的方法:
在app下build.gradle中的android闭包内添加:
useLibrary 'org.apache.http.legacy'
Apache HTTP Client
概述
HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包。
HttpClient的项目非常活跃,已经应用在很多的项目中,包括在Android中已经集成了HttpClient。
下载地址:http://hc.apache.org/downloads.cgi
GET请求
GET方法的操作代码示例如下:
//http地址
String httpUrl="http://10.0.2.2:8080/contact/android?par=HttpClient_android_Get";
//HttpGet连接对象
HttpGet httpRequest = new HttpGet(httpUrl);
//取得HttpClient对象
HttpClient httpclient = new DefaultHttpClient();
//请求HttpClient,取得HttpResponse
HttpResponse httpResponse = httpclient.execute(httpRequest);
//请求成功
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SCOK)
//取得返回的字符串
String strResult = EntityUtils.toString(httpResponse.getEntity());
案例
首先配置权限
<uses-permission android:name="android.permission.INTERNET"/>
布局的话就一个按钮,按钮的点击事件为Test
package com.example.a4_16httpclient;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Entity;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void Test(View view){
getRequest();
}
//使用Apache HTTP Client 的 GET请求
private void getRequest(){
new Thread(new Runnable() {
@Override
public void run() {
//换成自己的...
String path = "http://10.0.2.2:8080/contact/android?username=admin&password=admin";
//创建请求对象
HttpGet get = new HttpGet(path);
//创建HTTP客户端对象,用于发送请求
HttpClient httpClient = new DefaultHttpClient();
try {
//向服务器发送请求,并返回响应对象
HttpResponse response = httpClient.execute(get);
//获取响应的状态码
int status = response.getStatusLine().getStatusCode();
System.out.println("状态码为:"+status);
switch (status){
case HttpStatus.SC_OK:
//200
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity,"utf-8");
System.out.println(result);
break;
case HttpStatus.SC_NOT_FOUND:
//404
break;
case HttpStatus.SC_INTERNAL_SERVER_ERROR:
//500
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
测试效果:
服务器端:
客户端:
POST请求
使用POST方法进行参数传递时,需要额外进行一些设置,需要使用NameValuePair来保存要传递的参数,还需要设置所使用的字符集。
// http地址
String httpUrl = "String path = "http://10.0.2.2:8080/contact/android";
//HttpPost连接对象
HttpPost httpRequest =new HttpPost(httpUrl);
//使用NameValuePair来保存要传递的Post参数
List <NameValuePair> params = new ArrayList <NameValuePair>();
//添加要传递的参数
params.add(new BasicNameValuePair("par", "HttpClient_android-Post"));
//设置字符集
HttpEntity httpEntity = new UrlEncodedFormEntity(params,"gb2312");
//请求http
httpRequest.setEntity(httpEntity);
//取得默认的HttpClient
RequestHttpClient httpclient = new DefaultHttpClient();
//取得HttpResponse
HttpResponse httpResponse = httpclient.execute(httpRequest);
//HttpStatus.SC_OK表示连接成功
if (httpResponse.getStatusLinel).getStatusCode() == HttpStatus.SC_OK) {
//取得返回的字符串
String strResult = EntityUtils.toString(httpResponse.getEntityl);
}
案例
直接接在之前的代码上进行了,增加一个额外的Button(👇代码中点击事件为Test_POST)
package com.example.a4_16httpclient;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
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.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Entity;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//使用Apache HTTP Client 的 GET请求
public void Test(View view) {
getRequest();
}
//使用Apache HTTP Client 的 POST请求
public void Test_POST(View view) {
postRequest();
}
//使用Apache HTTP Client 的 POST请求 代码基本类似
private void postRequest() {
new Thread(new Runnable() {
@Override
public void run() {
//换成自己的...
String path = "http://10.0.2.2:8080/contact/android";
//创建请求对象
HttpPost post = new HttpPost(path);
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", "admin"));
params.add(new BasicNameValuePair("password", "admin"));
try {
HttpEntity entity = new UrlEncodedFormEntity(params);
post.setEntity(entity);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(post);
switch (response.getStatusLine().getStatusCode()) {
case HttpStatus.SC_OK:
String result = EntityUtils.toString(response.getEntity());
System.out.println(result);
break;
case HttpStatus.SC_NOT_FOUND:
Log.i("HttpClient", "404");
break;
case HttpStatus.SC_INTERNAL_SERVER_ERROR:
Log.i("HttpClient", "500");
break;
}
}
//捕获IO异常就够了
catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
//使用Apache HTTP Client 的 GET请求
private void getRequest() {
new Thread(new Runnable() {
@Override
public void run() {
//换成自己的...
String path = "http://10.0.2.2:8080/contact/android?username=admin&password=admin";
//创建请求对象
HttpGet get = new HttpGet(path);
//创建HTTP客户端对象,用于发送请求
HttpClient httpClient = new DefaultHttpClient();
try {
//向服务器发送请求,并返回响应对象
HttpResponse response = httpClient.execute(get);
//获取响应的状态码
int status = response.getStatusLine().getStatusCode();
System.out.println("状态码为:" + status);
switch (status) {
case HttpStatus.SC_OK:
//200
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "utf-8");
System.out.println(result);
break;
case HttpStatus.SC_NOT_FOUND:
//404
break;
case HttpStatus.SC_INTERNAL_SERVER_ERROR:
//500
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
效果的话是基本相同的,
客户端
服务器端