疑惑的地方
刚开始接触httpclient的同学可能会比较疑惑,因为你发现创建httpclient的方式有两种:
HttpClient client = new HttpClient();
CloseableHttpClient httpclient = HttpClients.createDefault();
到底该使用那种方式来创建httpclient,或者使用httpclient 又该导入哪些包。标号1中,是commons-httpclient 版本的创建方式,标号2是 httpclient的版本。这两个版本都可以处理http请求。我查阅了一下apach的官网看到了这样的一句话:
The Commons HttpClient project is now end of life, and is no longer being developed. It has been replaced by the Apache HttpComponents project in its HttpClient and HttpCore modules, which offer better performance and more flexibility.
大意是commons-httpclient项目不再提供更新和开发。看着这句话我们应该明白了,以后HttpClient client = new HttpClient() 这种创建httpclient 的方式,也应该会被我们弃用掉。新建的项目还是使用httpclient 吧。
之所以写这篇文档,也算是给自己做一个记录吧,httpclient4.5的版本变化还是比较大的,网络上的很多文档都是基于4.4写的,有点过时了。在学习官方文档,教程,源码的基础上,给自己留下一个学习的小脚印。
序言
HTTP也许是当今互联网上使用的最重要的协议了,尽管java.net包提供了访问HTTP资源的基本功能,但是因为它的不够灵活,使得Httpclient的应用更加广泛。HttpClient 不是一个浏览器,它是一个客户端的HTTP通信实现库,httpclient的目标是发送和接收报文。
小Demo
提供一个小demo ,看看这个httpclient到底该怎么用。
- pom.xml文件中导入jar包
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
- demo 程序
import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
/**
* describe
*
* @Author: soul
* @Date: 2016/12/5
* @since: JDK 1.8
* @Version: v1.0
*/
public class Demo {
public static void main(String[] args) throws IOException, URISyntaxException {
example();
}
public static void example() throws URISyntaxException, IOException {
//创建httpclient实例,采用默认的参数配置
CloseableHttpClient httpClient = HttpClients.createDefault();
//通过URIBuilder类创建URI
URI uri = new URIBuilder().setScheme("http")
.setHost("www.baidu.com")
.build();
HttpGet get = new HttpGet(uri) ; //使用Get方法提交
//请求的参数配置,分别设置连接池获取连接的超时时间,连接上服务器的时间,服务器返回数据的时间
RequestConfig config = RequestConfig.custom()
.setConnectionRequestTimeout(3000)
.setConnectTimeout(3000)
.setSocketTimeout(3000)
.build();
//配置信息添加到Get请求中
get.setConfig(config);
//通过httpclient的execute提交 请求 ,并用CloseableHttpResponse接受返回信息
CloseableHttpResponse response = httpClient.execute(get);
//服务器返回的状态
int statusCode = response.getStatusLine().getStatusCode() ;
//判断返回的状态码是否是200 ,200 代表服务器响应成功,并成功返回信息
if(statusCode == HttpStatus.SC_OK){
//EntityUtils 获取返回的信息。官方不建议使用使用此类来处理信息
System.out.println("Demo.example -------->" + EntityUtils.toString(response.getEntity() , Consts.UTF_8));
}else {
System.out.println("Demo.example -------->" + "获取信息失败");
}
}
}
上面的程序基本上能满足一些简单的数据请求。总结下httpclient的使用步骤:
- 创建httpclient实例
- 创建httpmethod 方法实例 ,最常用的是HttpGet,HttpPost 类
- httpclient 通过execute方法提交Get 或者Post 请求
- 使用CloseableHttpResponse 来接受服务器返回的状态信息和实体信息
- 关闭连接
HTTP 请求
所有的HTTP请求都有一个请求的起始行,由方法名,uri和HTTP协议版本组成 。
HttpClient很好的支持了HTTP/1.1规范中所有的HTTP方法:GET,HEAD,POST ,PUT ,DELETE ,TRACE 和 OPTIONS。每个方法都对应一个类:HttpGet,HttpHead,HttpPost,HttpPut,HttpDelete,HttpTrace和HttpOptions。
uri->统一资源定位符,包含了协议名称(http,https,ftp),主机名(www.xxx.com,www.xx.cn),可选端口(如果为80端口,可以省略),资源路径(/search),可选参数,可选片段等。
url如下:
http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=
HttpClient提供了URIBuilder工具类来简化创建。修改request URI .
URI uri = new URIBuilder().setScheme("http")
.setHost("www.google.com")
.setPath("/search")
.setParameter("q" ,"httpclient")
.setParamter("btnG" ,"google+Serach")
.build() ;
HttpGet get = new HttpGet(uri) ;
//除了使用URIBuilder工具类来创建连接,也可以直接采用字符串来定义uri
String url = http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq ;
HttpGet get = new HttpGet(url);
//效果也是一样的
Http 响应
HTTP响应是服务器接收并解析请求信息后返回给客户端的信息,它的起始行包含了一个协议版本,一个状态和描述状态的短语。Http/1.1 , 200 ,Ok
HTTP 实体
HttpClient 分为三种实体:
- 流式实体:内容来源于一个流,或者在运行中产生。流式实体不可重复。
- 自我包含:内存中的内容,通过独立的链接/其他的实体获得的内容。自我包含实体可重复
- 包装实体:从另外一个实体中获得内容。
服务器返回的信息封装在了entity中,客户端通过调用response.getEntity 可以拿到该实体内容。通过HttpEntity#getContent()方法,可以将数据转换成一个InputStream流。或者提供一个输出流给HttpEntity#writeTo(Outputstream)方法,它将会返回写入给定流的所有内容。官方其实是不建议使用EntityUtils类的,除非响应的实体来自于信任的Http服务器,并且知道它的长度。
释放低级别的资源
为了确保正确的释放资源,你必须关掉与实体相关的内容流,还必须关掉响应流。
- inputStrea.close()
- response.close()
参考: http://blog.csdn.net/u011179993/article/details/47123727
少年听雨歌楼上,红烛昏罗帐。
壮年听雨客舟中,江阔云低,断雁叫西风。
感谢支持!
---起个名忒难