HttpClient简介
现如今我们使用最多的协议莫过于:HTTP/HTTPS了,java提供了net包来支持HTTP协议,但并未提供许多应用程序所需的全部灵活性或功能,而Apache的HttpClient提供了更多的功能并且支持最新版本的HTTP标准。
特征:
- 基于标准的纯Java,HTTP版本1.0和1.1的实现。
- 在可扩展的OO框架中完全实现所有HTTP方法(GET,POST,PUT,DELETE,HEAD,OPTIONS和TRACE)。
- 支持使用HTTPS(基于SSL的HTTP)协议进行加密。
- 通过HTTP代理的透明连接。
- 通过CONNECT方法通过HTTP代理建立的隧道HTTPS连接。
- 基本,摘要,NTLMv1,NTLMv2,NTLM2会话,SNPNEGO,Kerberos身份验证方案。
- 自定义身份验证方案的插件机制。
- 可插拔的安全套接字工厂,使使用第三方解决方案更加容易。
- 支持在多线程应用程序中使用的连接管理。支持设置最大总连接数以及每个主机的最大连接数。检测并关闭陈旧的连接。
- 自动Cookie处理,用于从服务器读取Set-Cookie:标头,并在适当时在Cookie:标头中发回。
- 自定义Cookie策略的插件机制。
- 请求输出流以避免通过直接流到服务器的套接字来缓冲任何内容主体。
- 响应输入流通过直接从套接字流传输到服务器来有效读取响应主体。
- 在HTTP / 1.0中使用KeepAlive的持久连接以及在HTTP / 1.1中的持久性。
- 直接访问服务器发送的响应代码和标头。
- 设置连接超时的能力。
- 支持HTTP / 1.1响应缓存。
- 源代码可根据Apache许可免费获得。
HttpClient基本使用
HttpClient的最基本功能是执行HTTP方法。HTTP方法的执行涉及一个或多个HTTP请求/ HTTP响应交换,通常由HttpClient在内部处理。希望用户提供要执行的请求对象,并且HttpClient希望将请求传输到目标服务器,以返回相应的响应对象,如果执行不成功,则抛出异常。很自然,HttpClient API的主要入口是定义上述协定的HttpClient接口。
普通请求
CloseableHttpClient httpClient = HttpClients.createDefault();
//Get请求
HttpGet httpGet = new HttpGet("http://localhost/test");
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
} catch (IOException e) {
log.error("httpClient execute get request is fail,exceptionMessage:{}",e.getMessage());
}finally {
if (response != null){
try {
response.close();
} catch (IOException e) {
log.error("close httpClient response,exceptionMessage:{}",e.getMessage());
}
}
}
构建HTTP请求
所有HTTP请求的请求行均包含方法名称,请求URI和HTTP协议版本。HttpClient支持了在HTTP / 1.1规范中定义的所有HTTP方法:GET,HEAD, POST,PUT,DELETE, TRACE和OPTIONS。存在用于每种方法类型的特定类:HttpGet, HttpHead,HttpPost, HttpPut,HttpDelete, HttpTrace,和HttpOptions。
Request-URI是一个统一资源标识符,用于标识要在其上应用请求的资源。HTTP请求URI由协议方案,主机名,可选端口,资源路径,可选查询和可选片段组成。
try {
URI uri = new URIBuilder()
.setScheme("http")
.setHost("127.0.0.1")
.setPort(8080)
.setPath("/test")
.setParameter("name", "zs")
.build();
HttpGet httpGet = new HttpGet(uri);
} catch (URISyntaxException e) {
log.error("build uri is fail,exceptionMessage:{}",e.getMessage());
}
HTTP响应
HTTP响应是服务器在收到并解释了请求消息后将其发送回客户端的消息。该消息的第一行包含协议版本,后跟数字状态代码及其关联的文本短语。
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
System.out.println(response.getProtocolVersion());//HTTP/1.1
System.out.println(response.getStatusLine().getStatusCode()); //200
System.out.println(response.getStatusLine().getReasonPhrase()); //OK
System.out.println(response.getStatusLine().toString());//HTTP / 1.1 200 OK
使用邮件头
HTTP消息可以包含许多描述消息属性的标头,例如内容长度,内容类型等。HttpClient提供了检索,添加,删除和枚举标头的方法。
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie",
"c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie",
"c2=b; path=\"/\", c3=c; domain=\"localhost\"");
Header h1 = response.getFirstHeader("Set-Cookie");
System.out.println(h1); //Set-Cookie: c1=a; path=/; domain=localhost
Header h2 = response.getLastHeader("Set-Cookie");
System.out.println(h2);//Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
Header[] hs = response.getHeaders("Set-Cookie");
System.out.println(hs.length);//2
HTTP实体
HTTP消息可以携带与请求或响应关联的内容实体。实体可以在某些请求和响应中找到,因为它们是可选的。使用实体的请求称为实体封装请求。HTTP规范定义了两个包含请求方法的实体:POST和 PUT。通常期望响应包含内容实体。有例外的情况,如应对 HEAD方法204 No Content, 304 Not Modified,205 Reset Content 响应。
HttpClient根据内容的来源将其区分为三种:
- 流式: 从流中接收内容,或即时生成内容。特别地,此类别包括从HTTP响应接收的实体。流式实体通常不可重复。
- 自包含的: 内容在内存中或通过独立于连接或其他实体的方式获取。自包含实体通常是可重复的。这种类型的实体将主要用于封装HTTP请求的实体。
- 包装: 内容是从另一个实体获得的。
当从HTTP响应中流传输内容时,此区别对于连接管理很重要。对于由应用程序创建且仅使用HttpClient发送的请求实体,流式传输和自包含式之间的区别并不重要。在这种情况下,建议将不可重复的实体视为流,将可重复的实体视为独立的。
StringEntity myEntity = new StringEntity("重要消息",ContentType.create("text/plain","UTF-8"));
System.out.println(myEntity.getContentType())