我们在开发过程中经常会使用到HTTP协议作为我们数据交换的协议,本小节主要介绍一个开源的HTTP组件的使用。
1. 环境配置
1.1 下载安装
HTTP Components是Apache的一个子项目,地址是:
http://hc.apache.org/,主页中提供下载。使用过程及其简单,解压缩后直接将其lib目录下文件拷贝到classpath下即可。
1.2 使用Maven管理
如果您使用Maven管理你的项目,需要这样配置:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpcomponents.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>${httpcomponents.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>${httpcomponents.version}</version>
</dependency>
2. 示例代码
2.1 最简单的例子
最简单的例子当然是实现请求的处理,下面分别是GET和POST:
public void simpleGet() {
HttpGet get = new HttpGet("http://www.baidu.com");
try (CloseableHttpClient httpClient = new DefaultHttpClient();
CloseableHttpResponse response = httpClient.execute(get);) {
handleResponse(response);
} catch (IOException e) {
e.printStackTrace();
}
}
public void simplePost() {
HttpPost post = new HttpPost("http://www.baidu.com");
try (CloseableHttpClient httpClient = new DefaultHttpClient();
CloseableHttpResponse response = httpClient.execute(post);) {
handleResponse(response);
} catch (IOException e) {
e.printStackTrace();
}
}
注意我的代码使用了JDK 1.7的try语句块新特性,如果低于1.7版本请自行修改代码。
下面是处理响应的代码:
private void handleResponse(HttpResponse response) throws IOException {
int statusCode = 0;
if ((statusCode = response.getStatusLine().getStatusCode()) == 200) {
HttpEntity entity = response.getEntity();
System.out.println(entity.getContentType());
System.out.println(entity.getContentEncoding());
System.out.println(entity.getContentLength());
try (InputStream ins = response.getEntity().getContent();) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(ins));
String str = null;
while ((str = reader.readLine()) != null) {
System.out.println(str);
}
}
} else {
System.out.println("------------http error: statusCode is: "
+ statusCode);
}
}
2.2 增加URI方式
简单的一个请求我们可以处理,那么如果这个请求中需要包含参数呢?下面是代码:
public void simpleURIGet() throws URISyntaxException {
URI uri = new URIBuilder().setScheme("http").setHost("www.google.com")
.setPath("/search").setParameter("q", "httpclient")
.setParameter("btnG", "Google Search").setParameter("aq", "f")
.setParameter("oq", "").build();
HttpGet get = new HttpGet(uri);
System.out.println(get.getURI());
try (CloseableHttpClient httpClient = new DefaultHttpClient();
CloseableHttpResponse response = httpClient.execute(get);) {
handleResponse(response);
} catch (IOException e) {
e.printStackTrace();
}
}
public void simpleURIPost() throws URISyntaxException {
URI uri = new URIBuilder().setScheme("http").setHost("www.google.com")
.setPath("/search").setParameter("q", "httpclient")
.setParameter("btnG", "Google Search").setParameter("aq", "f")
.setParameter("oq", "").build();
HttpPost post = new HttpPost(uri);
System.out.println(post.getURI());
try (CloseableHttpClient httpClient = new DefaultHttpClient();
CloseableHttpResponse response = httpClient.execute(post);) {
handleResponse(response);
} catch (IOException e) {
e.printStackTrace();
}
}
对于POST,还可以这样:
public void simpleParamPost() throws UnsupportedEncodingException {
HttpPost post = new HttpPost("http://www.baidu.com");
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("name", "zhangsan"));
params.add(new BasicNameValuePair("password", "1234"));
post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
try (CloseableHttpClient httpClient = new DefaultHttpClient();
CloseableHttpResponse response = httpClient.execute(post);) {
handleResponse(response);
} catch (IOException e) {
e.printStackTrace();
}
}
2.3 对于Header的处理
对于请求头的处理,诸如设置字段值:
public void addHeadersGet() throws UnsupportedEncodingException {
HttpGet get = new HttpGet("http://www.baidu.com");
get.setHeader("User-Agent",
"Ahopedog/5.0 (Linux NT 5.1; rv:5.0) Gecko/20100101 FireDog/5.0");
get.setHeader("Accept-Charset", "GB2312,utf-8;q=0.7,*;q=0.7");
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("name", "zhangsan"));
params.add(new BasicNameValuePair("password", "1234"));
try (CloseableHttpClient httpClient = new DefaultHttpClient();
CloseableHttpResponse response = httpClient.execute(get);) {
handleResponse(response);
} catch (IOException e) {
e.printStackTrace();
}
}
public void addHeadersPost() throws UnsupportedEncodingException {
HttpPost post = new HttpPost("http://www.baidu.com");
post.setHeader("User-Agent",
"Ahopedog/5.0 (Linux NT 5.1; rv:5.0) Gecko/20100101 FireDog/5.0");
post.setHeader("Accept-Charset", "GB2312,utf-8;q=0.7,*;q=0.7");
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("name", "zhangsan"));
params.add(new BasicNameValuePair("password", "1234"));
post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
try (CloseableHttpClient httpClient = new DefaultHttpClient();
CloseableHttpResponse response = httpClient.execute(post);) {
handleResponse(response);
} catch (IOException e) {
e.printStackTrace();
}
}
处理响应头的话基本原理差不多,代码是这样:
public void handlePostResponseHeader() throws UnsupportedEncodingException {
HttpPost post = new HttpPost("http://www.baidu.com");
try (CloseableHttpClient httpClient = new DefaultHttpClient();
CloseableHttpResponse response = httpClient.execute(post);) {
Header[] headers = response.getAllHeaders();
for (Header h : headers) {
System.out.println(h.getName() + " : " + h.getValue());
}
Header serverHeader = response.getFirstHeader("server");
System.out.println(serverHeader.getName() + " : "
+ serverHeader.getValue());
} catch (IOException e) {
e.printStackTrace();
}
}
通过以上代码可以看出,HTTP component能够帮我们省去复杂的HTTP协议的建立连接、处理等操作,框架封装了细节。
3. Fluent方式
以上工作做完了之后,HTTP component仍然觉得不满足,他们认为还可以提供给我们更简洁编写自己代码的方案,于是Fluent来了:
3.1 最简单的调用
GET和POST都差不多:
public void simpleGet() {
Request request = Request.Get("http://www.baidu.com");
handleContent(request);
}
public void simplePost() {
Request request = Request.Post("http://www.baidu.com");
handleContent(request);
}
处理代码:
private void handleContent(Request request) {
Response response;
try {
response = request.execute();
System.out.println(response.returnContent());
} catch (ClientProtocolException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
3.2 增加参数
对于GET很简单,这里看看POST:
public void simpleURIPost() {
URI uri = URI.create("http://www.sina.com");
Request request = Request.Post(uri).bodyForm(
Form.form().add("username", "zhangsan").add("pasword", "pwd")
.build());
handleContent(request);
}
3.3 对于头和整个内容的处理
对于请求头、响应头和整个响应的处理,参见下面的代码:
public void simpleHeaderPost() {
Request request = Request.Post("http://www.sina.com.cn");
request.addHeader("User-Agent",
"Ahopedog/5.0 (Linux NT 5.1; rv:5.0) Gecko/20100101 FireDog/5.0");
request.setHeader("Accept-Charset", "GB2312,utf-8;q=0.7,*;q=0.7");
handleResponse(request);
handleEntity(request);
}
private void handleEntity(Request request) {
try {
HttpResponse response = request.execute().returnResponse();
HttpEntity entity = response.getEntity();
Header header = entity.getContentType();
System.out.println(header.getName() + ": " + header.getValue());
} catch (ClientProtocolException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void handleResponse(Request request) {
try {
HttpResponse response = request.execute().returnResponse();
Header[] headers = response.getAllHeaders();
for (Header header : headers) {
System.out.println("Header Name: " + header.getName()
+ "; Header Value: " + header.getValue());
}
} catch (ClientProtocolException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}