个人博客链接:http://wenzhuang.me
无论是B/S还是C/S,只要是涉及客户端与服务器的通信,那么如何处理HTTP请求就是无法避免的问题。
Java封装了HttpURLConnection提供给Java程序员做HTTP网络请求,然而使用HttpURLConnection做HTTP请求比较繁琐。如何简单快速地实现HTTP请求呢?Apache提供了一个专门用于处理HTTP请求的库HttpClient,使用起来方便快捷。
Java开发者使用HttpClient需要先到ApacheHttpClient的主页下载相关的jar包,官网地址http://hc.apache.org/httpclient-3.x/。
对于Android开发者来说,HttpClient几乎是最常用的用于处理HTTP请求的工具,在API21(Android4.4)及更早版本的SDK中,HttpClient被集成在SDK中,方便Android开发者处理HTTP请求。然而在API22及更新的Android SDK中HttpClient已经被去掉,然而开发者依然可以使用导入外部包的方式继续使用HttpClient进行开发。如果你是AndroidStudio用户,你还可以gradle进行包依赖管理,在build.gradle中加入如下声明:
android {
useLibrary 'org.apache.http.legacy'
}
Http请求最常用的是Get和Post请求,对于HTTP协议及其方法此处不再赘述。对于Post和Get请求,HttpClient都封装了相应的类和方法方便开发者的使用。
笔者使用HttpClient写了一个工具类HttpUtils,包含两个静态方法doGet(String)和doPost(String,Map)分别实现了Get请求和Post请求。源代码已上传至Github,地址:
https://github.com/WenZhuang/AndroidUtils/blob/master/HttpUtils.java
以下是doGet方法的源代码,方法调用者需要传入一个目标URL地址作为参数,响应成功时返回响应字符串,失败时返回相应的响应码(如404)。首先需要创建一个HttpClient对象和一个HttpGet对象,给HttpGet设置请求参数(如设置响应超时时间等)这部分并非是必须的。HttpClient对象只需调用execute(HttpGet)方法就可以获得一个HttpResponse对象,该对象包含从服务器获取的HTTP响应。调用getEntity方法获取Http响应体。
public static String doGet(String url){
String responseStr = "Fail";
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpRequest = new HttpGet(url);
//设置请求参数
HttpParams params = new BasicHttpParams();
// 从连接池中获取连接的超时时间
ConnManagerParams.setTimeout(params, 1000);
// 通过网络与服务器建立连接的超时时间
HttpConnectionParams.setConnectionTimeout(params, 3000);
// 读响应数据的超时时间
HttpConnectionParams.setSoTimeout(params, 5000);
httpRequest.setParams(params);
HttpResponse httpResponse = httpClient.execute(httpRequest);
final int ret = httpResponse.getStatusLine().getStatusCode();
if (ret == HttpStatus.SC_OK) {
responseStr = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
} else {
responseStr = String.valueOf(ret);
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return responseStr;
}
以下是doPost方法的源代码。调用者需要传入一个目标URL地址和一个Map作为参数。响应成功时返回响应字符串,失败时返回相应的响应码。调用者在调用doPost前需要将请求参数以键值对的方式存入Map中,再将Map作为doPost的参数。首先需要创建一个HttpClient对象和一个HttpPost对象,依次取出Map里的参数存入包含BasicNameValuePair的list中。调用HttpPost的setEntity的方法装入请求体。HttpClient对象调用execute(HttpPost)方法就可以获得一个HttpResponse对象,处理方式与doGet方法相同。
public static String doPost(String url, Map<String,String> map) {
String responseStr = "Fail";
try {
HttpPost httpRequest = new HttpPost(url);
//设置请求参数
HttpParams params = new BasicHttpParams();
// 从连接池中获取连接的超时时间
ConnManagerParams.setTimeout(params, 1000);
// 通过网络与服务器建立连接的超时时间
HttpConnectionParams.setConnectionTimeout(params, 3000);
// 读响应数据的超时时间
HttpConnectionParams.setSoTimeout(params, 5000);
httpRequest.setParams(params);
// 下面开始跟服务器传递数据,使用BasicNameValuePair
List<BasicNameValuePair> paramsList = new ArrayList<>();
for(String key : map.keySet()){
paramsList.add(new BasicNameValuePair(key , map.get(key)));
}
httpRequest.setEntity(new UrlEncodedFormEntity(
paramsList, HTTP.UTF_8));
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpRequest);
final int ret = httpResponse.getStatusLine().getStatusCode();
if (ret == HttpStatus.SC_OK) {
responseStr = EntityUtils.toString(httpResponse.getEntity(),HTTP.UTF_8);
} else {
responseStr = String.valueOf(ret);
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return responseStr;
}