HttpClient是Apache开源组织提供的HTTP网络访问接口,HttpClient封装了访问http的请求头,参数,内容体,响应等等,有很多API,可以很方便的处理session,cookie等(在某些情况下,用HttpURLConnection访问一些特定的页面,处理session,cookie相当复杂),比较稳定,发送请求、接收响应都很简单。
可以简单的分为几步执行:
1.1 创建请求对象:GET方式参数拼接在URL结尾,POST方式需要使用setEntity(HttpEntity entity)方法来设置请求参数;
1.2 获取HttpClient对象;
1.3 发送请求;
1.4 得到响应,获取数据;
直接上代码,注释已经解释的很清楚了。
1. 首先设置一些基本的参数来获取线程安全的HttpClient对象
/**
* 设置一些基本的参数来获取线程安全的HttpClient对象
*
* @return 返回线程安全的HttpClient对象
*/
private static HttpClient getHttpClient() {
/* 1. 设置一些基本参数,如Http版本、编码格式和参数设置 */
HttpParams httpParams = new BasicHttpParams();
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(httpParams, "UTF-8");
HttpProtocolParams.setUseExpectContinue(httpParams, true);
/* 2. 超时设置 */
/* 从连接池中取连接的超时时间 */
ConnManagerParams.setTimeout(httpParams, 20000);
/* 连接超时 */
HttpConnectionParams.setConnectionTimeout(httpParams, 20000);
/* 请求超时 */
HttpConnectionParams.setSoTimeout(httpParams, 20000);
/* 3. 设置我们的HttpClient支持HTTP和HTTPS两种模式 */
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", SSLSocketFactory
.getSocketFactory(), 443));
/* 4. 使用线程安全的连接管理来创建HttpClient */
ClientConnectionManager manager = new ThreadSafeClientConnManager(
httpParams, registry);
return new DefaultHttpClient(manager, httpParams);
}
2.1. HttpClient Post请求方式
<pre name="code" class="java">/**
* HttpClient Post请求方式
*/
public static boolean onLinkNetPost(String url, List<NameValuePair> nvpsList) {
try {
// 判断传递进来的url连接地址是否为空
if (null == url) {
return false;
}
/* 1.1 创建POST请求,并设置Url地址的名值对及其编码格式,然后设置Entity */
Log.e("post", url);
HttpPost httpPost = new HttpPost(url);
if (null != nvpsList) {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(
nvpsList, "UTF-8");
httpPost.setEntity(entity);
}
/* 1.2获取HttpClient对象,并发送请求,得到响应 */
HttpClient httpClient = getHttpClient();
// 1.3发送请求,获取服务器返回的相应对象
HttpResponse httpResponse = httpClient.execute(httpPost);
/* 1.4 从响应中获取数据 */
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
return false;
}
HttpEntity httpEntity = httpResponse.getEntity();
String object = (httpEntity == null) ? null : (EntityUtils
.toString(httpEntity, "UTF-8"));
Log.e("object", object);
return true;
} catch (Exception e) {
e.printStackTrace();
Log.e("Exception=", e.getMessage() + "");
Log.e("e", e.getMessage() + "");
return false;
}
}
2.2. HttpClient Get请求方式
<pre name="code" class="java"> /**
* HttpClient Get请求方式
*/
public static boolean onLinkNetGet(String url, Map<String, String> params) {
try {
// GET方式参数拼接在URL结尾
StringBuilder sb = new StringBuilder();
sb.append(url).append("?");
if (params != null && params.size() != 0) {
for (Map.Entry<String, String> entry : params.entrySet()) {
// 如果请求参数中有中文,需要进行URLEncoder编码
sb.append(entry.getKey())
.append("=")
.append(URLEncoder.encode(entry.getValue(), "utf-8"));
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb.toString());
Log.d("sb", sb.toString());
}
/* 1.1 创建Get请求,并设置Url地址 */
HttpGet httpGet = new HttpGet(sb.toString());
Log.e("get", sb.toString());
/* 1.2 获取HttpClient对象,并发送请求,得到响应 */
HttpClient httpClient = getHttpClient();
// 1.3发送请求,获取服务器返回的相应对象
HttpResponse httpResponse = httpClient.execute(httpGet);
/* 1.4 从响应中获取数据 */
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
return false;
}
HttpEntity httpEntity = httpResponse.getEntity();
String object = (httpEntity == null) ? null : (EntityUtils
.toString(httpEntity, "UTF-8"));
System.out.println(object);
Log.e("object", object);
return true;
} catch (Exception e) {
e.printStackTrace();
Log.e("Exception=", e.getMessage() + "");
Log.e("e", e.getMessage() + "");
return false;
}
}
2.3. HttpClient Put请求方式
<pre name="code" class="java">// Put方式
public static boolean onLinkNetPut(String url, Map<String, String> params) {
try {
/* 1. 判断传递进来的url连接地是否为空 */
if (null == url) {
return false;
}
StringBuilder sb = new StringBuilder();
sb.append(url).append("?");
if (params != null && params.size() != 0) {
for (Map.Entry<String, String> entry : params.entrySet()) {
// 如果请求参数中有中文,需要进行URLEncoder编码
sb.append(entry.getKey())
.append("=")
.append(URLEncoder.encode(entry.getValue(), "utf-8"));
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb.toString());
Log.d("sb", sb.toString());
}
/* 1.1 创建httpPut请求,并设置Url地址 */
HttpPut httpPut = new HttpPut(sb.toString());
Log.e("start", sb.toString());
/* 1.2 获取HttpClient对象,并发送请求,得到响应 */
HttpClient httpClient = getHttpClient();
// 1.3发送请求,获取服务器返回的相应对象
HttpResponse httpResponse = httpClient.execute(httpPut);
/* 1.4从响应中获取数据 */
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
return false;
}
HttpEntity httpEntity = httpResponse.getEntity();
String object = (httpEntity == null) ? null : (EntityUtils
.toString(httpEntity, "UTF-8"));
Log.e("object", object);
return true;
} catch (Exception e) {
e.printStackTrace();
Log.e("Exception=", e.getMessage() + "");
Log.e("e", e.getMessage() + "");
return false;
}
}
3. 使用
//Login Post请求方式
public static boolean Login(String login_name, String password) {
List<NameValuePair> nvpsList =new ArrayList<NameValuePair>();
try {
nvpsList.add(new BasicNameValuePair("login_name",login_name));
nvpsList.add(new BasicNameValuePair("password",password));
} catch (Exception e) {
e.printStackTrace();
}
String url = "Your Url";
return onLinkNetPost(url,nvpsList);
}
其他开源联网框架
AsyncHttpClient
除了上述Android官方推荐的联网框架以外,在开源世界里关于联网框架真是太多太多了,例如afinal,xutils等等,都是一些开源大牛自己封装的联网框架,并且在GitHub开源社区中可以 下载到,其实类似的开源联网框架基本上也是基于HttpUrlConnection的进一步封装,大大提高了性能,同时更加简化了使用方法,这里使用AsyncHttpClient作为案例,其他的联网框架大家可以去网上找,下载使用试试便可。 AsyncHttpClient是一个非常优秀的联网框架,不仅支持所有Http请求的方式,而且还支持文件的上传和下载,要知道用HttpUrlConnection写一个文件上传和下载健全功能是很需要花费一定时间和精力的,因为请求头实在是太多了,稍有不慎就会写错。但是AsyncHttpClient已经封装好了这些“麻烦”,我们只需要下载到AsyncHttpClient的jar包或者 源码导入项目中,Http,上传,下载等等,只需要几个简单的api即可搞定。 AsyncHttpClient的GitHub主页:https://github.com/AsyncHttpClient/async-http-client/AsyncHttpClient发送GET请求
1,将下载好的源码拷贝到src目录下
2,创建一个AsyncHttpClient的对象
3,调用该类的get方法发送GET请求,传入请求资源地址URL,创建AsyncHttpResponseHandler对象
4,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法
/**
* 通过AsyncHttpClient发送GET请求
*/
public void loginByAsyncHttpGet() {
String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=zhangsan&password=123;
AsyncHttpClient client = new AsyncHttpClient();
client.get(path, new AsyncHttpResponseHandler() {
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2,
Throwable arg3) {
// TODO Auto-generated method stub
Log.i(TAG, 请求失败: + new String(arg2));
}
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
// TODO Auto-generated method stub
Log.i(TAG, 请求成功: + new String(arg2));
}
});
}
AsyncHttpClient发送POST请求
1,将下载好的源码拷贝到src目录下
2,创建一个AsyncHttpClient的对象
3,创建请求参数,RequestParams对象
4,调用该类的post方法发POST,传入请求资源地址URL,请求参数RequestParams,创建AsyncHttpResponseHandler对象
5,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法
/**
* 通过AsyncHttpClient发送POST请求
*/
public void loginByAsyncHttpPost() {
String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put(username, zhangsan);
params.put(password, 123);
client.post(path, params, new AsyncHttpResponseHandler() {
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2,
Throwable arg3) {
// TODO Auto-generated method stub
Log.i(TAG, 请求失败: + new String(arg2));
}
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
// TODO Auto-generated method stub
Log.i(TAG, 请求成功: + new String(arg2));
}
});
}
AsyncHttpClient上传文件
1,将下载好的源码拷贝到src目录下
2,创建一个AsyncHttpClient的对象
3,创建请求参数,RequestParams对象,请求参数仅仅包含文件对象即可,例如:
params.put(profile_picture, new File(/sdcard/pictures/pic.jpg));
4,调用该类的post方法发POST,传入请求资源地址URL,请求参数RequestParams,创建AsyncHttpResponseHandler对象
5,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法
判断网络连接状态
很多时候对于手机或者平板电脑这样的手持设备,我们是不知道它们的网络连接状态的,在联网的时候我们必须得保证设备的网路是否正常,是否可以连接上互联网,或者我们在进行大量数据上传或者下载,例如下载网路视频,看网路电视等等,我们必须得为用户省钱,这样大数据的传输显然是不能使用用户昂贵的数据流量的,而是判断当前网络是不是在wifi下,使用WiFi来进行大数据的传输,会给用户更好的体验,那么下面这个工具类就是用来判断设备网络连接状态的,不仅判断了当前设置手机网络下还是WiFi环境下,而且如果手机网络下还需要设置运营商的代理IP和端口。
/**
* 判断网络状态的工具类
*
*/
public class NetworkUtil {
/* 代码IP */
private static String PROXY_IP = null;
/* 代理端口 */
private static int PROXY_PORT = 0;
/**
* 判断当前是否有网络连接
*
* @param context
* @return
*/
public static boolean isNetwork(Context context) {
boolean network = isWifi(context);
boolean mobilework = isMobile(context);
if (!network && !mobilework) { // 无网络连接
Log.i(NetworkUtil, 无网路链接!);
return false;
} else if (network == true && mobilework == false) { // wifi连接
Log.i(NetworkUtil, wifi连接!);
} else { // 网络连接
Log.i(NetworkUtil, 手机网路连接,读取代理信息!);
readProxy(context); // 读取代理信息
return true;
}
return true;
}
/**
* 读取网络代理
*
* @param context
*/
private static void readProxy(Context context) {
Uri uri = Uri.parse(content://telephony/carriers/preferapn);
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
PROXY_IP = cursor.getString(cursor.getColumnIndex(proxy));
PROXY_PORT = cursor.getInt(cursor.getColumnIndex(port));
}
cursor.close();
}
/**
* 判断当前网络是否是wifi局域网
*
* @param context
* @return
*/
public static boolean isWifi(Context context) {
ConnectivityManager manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (info != null) {
return info.isConnected(); // 返回网络连接状态
}
return false;
}
/**
* 判断当前网络是否是手机网络
*
* @param context
* @return
*/
public static boolean isMobile(Context context) {
ConnectivityManager manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (info != null) {
return info.isConnected(); // 返回网络连接状态
}
return false;
}
}